【翻译】Spring Security - 如何解决WebSecurityConfigurerAdapter类已被弃用的问题?
原文链接:Spring Security - How to Fix WebSecurityConfigurerAdapter Deprecated
原文作者:Nam Ha Minh
原文发表日期:2022年6月1日
在这篇短文中,我想分享如何在使用Spring Security的Spring应用中避免“WebSecurityConfigurerAdapter类已被弃用”的警告。
也许你习惯于使用一个扩展自WebSecurityConfigurerAdapter抽象类的Spring配置类,就像这样:
@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... } }
这在Spring Security 5.6.5及更旧版本或Spring Boot 2.6.8及更旧版本没有问题。然而,如果你的项目使用Spring Security 5.7.1及更新版本或者Spring Boot 2.7.0及更新版本,你的IDE会警告你:
类WebSecurityConfigurerAdapter已被弃用
那么,为什么Spring Security弃用了WebSecurityConfigurerAdapter?它的继任者是什么?
这是因为Spring框架的开发者鼓励用户使用基于组件的(component-based)的安全配置。
在以前的用法中,我们扩展WebSecurityConfigurerAdapter类并且覆盖配置HttpSecurity和WebSecurity的方法;在新的用法中,我们得分别声明类型为SecurityFilterChain和WebSecurityCustomizer的bean,就像下面这样:
@Configuration public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { } @Bean public WebSecurityCustomizer webSecurityCustomizer() { } }
下面是从旧的安全配置转向基于组件的配置的代码示例。首先,让我们看看典型的扩展自WebSecurityConfigurerAdapter的安全配置类,如下所示:
1 @Configuration 2 @EnableWebSecurity 3 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 4 5 @Bean 6 public UserDetailsService userDetailsService() { 7 return new ShopmeUserDetailsService(); 8 } 9 10 @Bean 11 public BCryptPasswordEncoder passwordEncoder() { 12 return new BCryptPasswordEncoder(); 13 } 14 15 @Override 16 protected void configure(HttpSecurity http) throws Exception { 17 http.authorizeRequests().antMatchers("/login").permitAll() 18 .antMatchers("/users/**", "/settings/**").hasAuthority("Admin") 19 .hasAnyAuthority("Admin", "Editor", "Salesperson") 20 .hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper") 21 .anyRequest().authenticated() 22 .and().formLogin() 23 .loginPage("/login") 24 .usernameParameter("email") 25 .permitAll() 26 .and() 27 .rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789") 28 .and() 29 .logout().permitAll(); 30 31 http.headers().frameOptions().sameOrigin(); 32 } 33 34 @Override 35 public void configure(WebSecurity web) throws Exception { 36 web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**"); 37 } 38 }
下面是不使用WebSecurityConfigurerAdapter的新的安全配置:
1 package net.codejava; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; 7 import org.springframework.security.core.userdetails.UserDetailsService; 8 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 9 import org.springframework.security.web.SecurityFilterChain; 10 11 @Configuration 12 public class SecurityConfiguration { 13 14 @Bean 15 public UserDetailsService userDetailsService() { 16 return new ShopmeUserDetailsService(); 17 } 18 19 @Bean 20 public BCryptPasswordEncoder passwordEncoder() { 21 return new BCryptPasswordEncoder(); 22 } 23 24 @Bean 25 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 26 http.authorizeRequests().antMatchers("/login").permitAll() 27 .antMatchers("/users/**", "/settings/**").hasAuthority("Admin") 28 .hasAnyAuthority("Admin", "Editor", "Salesperson") 29 .hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper") 30 .anyRequest().authenticated() 31 .and().formLogin() 32 .loginPage("/login") 33 .usernameParameter("email") 34 .permitAll() 35 .and() 36 .rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789") 37 .and() 38 .logout().permitAll(); 39 40 http.headers().frameOptions().sameOrigin(); 41 42 return http.build(); 43 } 44 45 @Bean 46 public WebSecurityCustomizer webSecurityCustomizer() { 47 return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**"); 48 }
以上就是如何在使用的Spring Security的Spring应用中避免“类WebSecurityConfigurerAdapter已被弃用”的警告的方法。你需要声明SecurityFilterChain和WebSecurityCustomizer两个bean而不是覆盖WebSecurityConfigurerAdapter类的方法。
注意:如果你不想修改你现在的代码,那么你的的Spring Boot版本应该低于2.7.0、Spring Security版本低于5.7.1。
我希望这篇文章能帮助到你,感谢阅读。
参考资料:Spring Security without the WebSecurityConfigurerAdapter