![]() |
VOOZH | about |
Spring Security is a powerful authentication and access control framework for Java applications specially for those built with the Spring Framework. With the release of Spring Security 6, several enhancements and changes have been introduced to simplify the security configuration and provide better performance and security features.
This article aims to provide a comprehensive step-by-step process for migrating the Spring Boot application from Spring Security 5 to Spring Security 6. We will cover the key changes, update configurations, and ensure that the application leverages the latest features of Spring Security 6.
First, we need to update the project dependencies to include the latest version of the Spring Security 6.
Update the pom.xml to include the Spring Security 6 dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.0.0</version> <!-- Ensure this matches your Spring Boot version -->
</dependency>If you are using the Gradle, update the build.gradle to include the Spring Security 6 dependency.
implementation 'org.springframework.boot:spring-boot-starter-security:3.0.0' // Ensure this matches your Spring Boot versionOne of the major change in the Spring Security 6 is the removal of WebSecurityConfigurerAdapter class. This class can be previously used to customize the security configuration. In Spring Security 6, we should now define the SecurityFilterChain bean and configure the HTTP security using HttpSecurity DSL.
In Spring Security 6, the configuration can be done through the SecurityFilterChain and the HttpSecurity DSL. Here the detailed example of how to migrate the security configuration of the application.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
}@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.httpBasic(withDefaults());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}In Spring Security 6, it is recommended to use the PasswordEncoder beans for password encoding. The use of {noop} prefix for the plain text passwords is deprecated. Here's how you should update the password encoding configuration:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}If application uses the Spring Boot Actuator, we might need to adjust its the security settings to fit the new configuration style of application.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")
.anyRequest().authenticated();
}@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.httpBasic(withDefaults());
return http.build();
}CSRF protection is enabled by default in Spring Security. If you need to customize it, we can do using the csrf() method in HttpSecurity configuration of the application.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf
.ignoringRequestMatchers("/api/**")
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.httpBasic(withDefaults());
return http.build();
}After updating the configuration thoroughly test all the security aspects of the application. We can ensure that the authentication, authorization and custom configuration are functioning correctly.
Migrating from Spring Security 5 to Spring Security 6 involves updating dependencies, refactoring the security configurations and ensuring that the application adheres to new best practices. By following this article, we can leverage the enhanced features and security improvements offered by the Spring Security 6.