Spring Security - How to Fix WebSecurityConfigurerAdapter Deprecated
- Details
- Written by Nam Ha Minh
- Last Updated on 21 July 2024   |   Print Email
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// configure HTTP security...
}
@Override
public void configure(WebSecurity web) throws Exception {
// configure Web security...
}
}This is fine with Spring Security version 5.6.5 or older, or with Spring Boot version 2.6.8 or older. However, if your project uses Spring Security 5.7.1 or newer, or Spring Boot 2.7.0 or newer, you will get this warning in your IDE:The type WebSecurityConfigurerAdapter is deprecated
So, why Spring Security deprecates the use of WebSecurityConfigurerAdapter ?, and what is the alternative?Well, it’s because the developers of Spring framework encourage users to move towards a component-based security configuration.So, instead of extending WebSecurityConfigurerAdapter and overriding methods for configuring HttpSecurity and WebSecurity as in the old way - Now you to declare two beans of type SecurityFilterChain and WebSecurityCustomizer as follows:@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
}
}For your reference, below is a code example of migrating security configuration towards component-based approach. First, let’s look at a typical security configuration class with WebSecurityConfigurerAdapter as shown below:@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService userDetailsService() {
return new ShopmeUserDetailsService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll()
.antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
.hasAnyAuthority("Admin", "Editor", "Salesperson")
.hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login")
.usernameParameter("email")
.permitAll()
.and()
.rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
.and()
.logout().permitAll();
http.headers().frameOptions().sameOrigin();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
}
}And below is an alternative, without WebSecurityConfigurerAdapter:package net.codejava;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfiguration {
@Bean
public UserDetailsService userDetailsService() {
return new ShopmeUserDetailsService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll()
.antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
.hasAnyAuthority("Admin", "Editor", "Salesperson")
.hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login")
.usernameParameter("email")
.permitAll()
.and()
.rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
.and()
.logout().permitAll();
http.headers().frameOptions().sameOrigin();
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
}
} Declare a bean of type AuthenticationManager:
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
} Declare a bean of type AuthenticationProvider:
In case you need to expose a bean of type AuthenticationProvider, such as DaoAuthenticationProvider, use the following code:@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}and specify this authentication provider for HttpSecurity in the code of SecurityFilterChain as follows:http.authenticationProvider(authenticationProvider());That’s how to remove the warning “The type WebSecurityConfigurerAdapter is deprecated” in Spring-based application with Spring Security. You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class. NOTES: If you don’t want to change your current code, you should keep Spring Boot version lower than 2.7.0 or Spring Security version older than 5.7.1. In Spring Security 6.x, the WebSecurityConfigurerAdapter class is even removed, and the aforementioned solution still applies. I recommend you check this guide to learn more about solutions for other deprecated methods in Spring Security.I hope you have found this post helpful. Thanks for reading.
Reference:
Spring Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Comments
that WebSecurityConfigurerAdapter is deprecated and you equally provided a solution.
Can you please explain to me where this class comes from : ShopmeUserDetailsService ?
Below is part of your code
@Bean
public UserDetailsService userDetailsService() {
return new ShopmeUserDetailsService();
}
Thanks in advance