The Master Class of "Learn Spring Security" is out:
1. Overview
This article is an introduction to Java configuration for Spring Security which enables users to easily configure Spring Security without the use of XML.
Java configuration was added to the Spring framework in Spring 3.1 and extended to Spring Security in Spring 3.2 and is defined in a class annotated @Configuration.
2. Maven Setup
To use Spring Security in a Maven projects, we first need to have the spring-security-core dependency in the project pom.xml:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>4.1.3.RELEASE</version> </dependency>
The latest version can always be found here.
3. Web Security with Java Configuration
Let’s start with a basic example of a Spring Security Java configuration:
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user") .password("password").roles("USER"); } }
As you may have noticed, the configuration sets up a basic in-memory authentication config.
4. HTTP Security
To enable HTTP Security in Spring, we need to extend the WebSecurityConfigurerAdapter to provide a default configuration in the configure(HttpSecurity http) method:
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and().httpBasic(); }
The above default configuration makes sure any request to the application is authenticated with form based login or HTTP basic authentication.
Also, it is exactly similar to the following XML configuration:
<http> <intercept-url pattern="/**" access="authenticated"/> <form-login /> <http-basic /> </http>
5. Form Login
Interestingly, Spring Security generates a login page automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login:
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .loginPage("/login").permitAll(); }
Here the automatically generated login page is convenient to get up and running quickly.
6. Authorization with Roles
Let’s now configure some simple authorization on each URL using roles:
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/home").access("hasRole('USER')") .antMatchers("/admin/**").hasRole("ADMIN") .and() // some more method calls .formLogin(); }
Notice how we’re using both the type-safe API – hasRole – but also the expression based API, via access.
7. Logout
As many other aspects of Spring Security, logout has some great defaults provided by the framework.
By default, a logout request invalidates the session, clears any authentication caches, clears the SecurityContextHolder and redirects to login page.
Here is a simple logout config:
protected void configure(HttpSecurity http) throws Exception { http.logout(); }
However, if you want to get more control over the available handlers, here’s what a more complete implementation will look like:
protected void configure(HttpSecurity http) throws Exception { http.logout().logoutUrl("/my/logout") .logoutSuccessUrl("/my/index") .logoutSuccessHandler(logoutSuccessHandler) .invalidateHttpSession(true) .addLogoutHandler(logoutHandler) .deleteCookies(cookieNamesToClear) .and() // some other method calls }
8. Authentication
Let’s have a look at another way of allowing authentication with Spring Security.
8.1. In-Memory Authentication
We’ll start with a simple, in-memory configuration:
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER") .and() .withUser("admin").password("password").roles("USER", "ADMIN"); }
8.2. JDBC Authentication
To move that to JDBC, all you have to do is to define a data source within the application – and use that directly:
@Autowired private DataSource dataSource; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource) .withDefaultSchema() .withUser("user").password("password").roles("USER") .and() .withUser("admin").password("password").roles("USER", "ADMIN"); }
9. Conclusion
In this quick tutorial, we went over the basics of Java Configuration for Spring Security and focused on the code samples that illustrate the simplest configuration scenarios.