Spring Security - How to Fix WebSecurityConfigurerAdapter Deprecated
- Details
- Written by Nam Ha Minh
- Last Updated on 21 July 2024   |   Print Email
In this short article, I’d like to share how to get rid of the warning saying that “The type WebSecurityConfigurerAdapter is deprecated” in Spring-based applications that use Spring Security for authentication and authorization. You may see this warning message when you migrate your Spring projects to recent version of Spring Boot or Spring Security, such as Spring Boot 3.x and Spring Security 6.x.
Perhaps you are used to have a Spring configuration class that extends the WebSecurityConfigurerAdapter abstract class like this:
@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:
In case you need to expose a bean of type AuthenticationManager, you can put the following code:
@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:
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