Spring Security:在Spring Boot 2.7.0中升级已弃用的WebSecurityConfigurerAdapter。
Spring Security:在Spring Boot 2.7.0中升级已弃用的WebSecurityConfigurerAdapter。
我正在尝试更新WebSecurityConfigurerAdapter
,因为它已被弃用。该类的配置如下:\n
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired UsuariService userDetailsService; @Autowired private AuthEntryPointJwt unauthorizedHandler; @Bean public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); } @Override public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() .antMatchers("/api/auth/**").permitAll().antMatchers("/api/test/**").permitAll().antMatchers("/api/v1/**").permitAll().anyRequest() .authenticated(); http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); } }
\n现在,没有WebSecurityConfigurerAdapter
,我像这样重新定义了同样的类:\n
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig { @Autowired UsuariService userDetailsService; @Autowired private AuthEntryPointJwt unauthorizedHandler; @Bean public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); } @Bean AuthenticationManager authenticationManager(AuthenticationManagerBuilder builder) throws Exception { return builder.userDetailsService(userDetailsService).passwordEncoder(encoder()).and().build(); } @Bean public PasswordEncoder encoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() .antMatchers("/api/auth/**").permitAll() .antMatchers("/api/test/**").permitAll() .antMatchers("/api/v1/**").permitAll() .anyRequest().authenticated(); http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } }
\n但不幸的是,我遇到了以下错误:\n
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'filterChain' defined in class path resource [cit/base/app/security/WebSecurityConfig.class]: Unsatisfied dependency expressed through method 'filterChain' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration.httpSecurity' defined in class path resource [org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.config.annotation.web.builders.HttpSecurity]: Factory method 'httpSecurity' threw exception; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration$EnableGlobalAuthenticationAutowiredConfigurer@3fdc705c to already built object
\n我将非常感激任何形式的帮助,非常欢迎。
问题:在Spring Boot 2.7.0中,WebSecurityConfigurerAdapter已被弃用,需要进行升级。
解决方法:
1. 创建一个名为SpringSecurityConfig的类。
2. 在类上添加注解(prePostEnabled = true)。
3. 在类中添加filterChain方法,参数为HttpSecurity,返回类型为SecurityFilterChain,抛出异常Exception。
4. 在filterChain方法中,禁用csrf保护,禁用跨域保护,配置请求权限。
5. 使用requestMatchers方法配置允许访问的请求,使用permitAll方法设置允许所有用户访问的请求。
6. 使用anyRequest方法配置所有其他请求需要进行身份验证。
7. 在filterChain方法中,使用oauth2ResourceServer方法配置OAuth2资源服务器。
8. 返回http.build()构建的SecurityFilterChain对象。
整理成的文章如下:
在Spring Boot 2.7.0中,WebSecurityConfigurerAdapter已被弃用。为了解决这个问题,你需要进行升级。下面是升级后的代码示例:
(prePostEnabled = true) public class SpringSecurityConfig { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable().cors().disable().authorizeHttpRequests() .requestMatchers("/user/register").permitAll() .anyRequest().authenticated() .and() .oauth2ResourceServer(); return http.build(); } }
在上面的示例中,我们创建了一个名为SpringSecurityConfig的类,并在类上添加了注解(prePostEnabled = true)。然后,我们在类中添加了一个filterChain方法,该方法接受HttpSecurity作为参数,并将SecurityFilterChain作为返回类型,还抛出了异常Exception。
在filterChain方法中,我们禁用了csrf保护,并禁用了跨域保护。然后,我们使用requestMatchers方法配置了允许访问的请求,使用permitAll方法设置了允许所有用户访问的请求。最后,我们使用anyRequest方法配置了所有其他请求需要进行身份验证。
在filterChain方法中,我们使用oauth2ResourceServer方法配置了OAuth2资源服务器。最后,我们返回了通过http.build()方法构建的SecurityFilterChain对象。
通过以上的步骤,你可以成功升级到Spring Boot 2.7.0,并解决WebSecurityConfigurerAdapter被弃用的问题。
Spring Boot 2.7.0中存在一个问题,即在使用过时的WebSecurityConfigurerAdapter时可能会导致配置无效。下面是解决该问题的方法。
首先,在BeanConfiguration类中添加一个bCryptPasswordEncoder方法,返回一个BCryptPasswordEncoder实例。
public class BeanConfiguration { public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } }
其次,在SpringSecurityConfiguration类中,声明一个AuthenticationManager和一个UserDetailsService,并实现filterChain方法。在该方法中,使用http.getSharedObject(AuthenticationManagerBuilder.class)获取AuthenticationManagerBuilder实例,然后调用userDetailsService方法将UserDetailsService传递给它。接着,使用authenticationManagerBuilder.build()构建AuthenticationManager实例。最后,使用http对象配置Spring Security的各项设置。
public class SpringSecurityConfiguration { AuthenticationManager authenticationManager; UserDetailsService userDetailsService; public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); authenticationManagerBuilder.userDetailsService(userDetailsService); authenticationManager = authenticationManagerBuilder.build(); http.csrf().disable().cors().disable().authorizeHttpRequests().antMatchers("/api/v1/account/register", "/api/v1/account/auth").permitAll() .anyRequest().authenticated() .and() .authenticationManager(authenticationManager) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); return http.build(); } }
最后,在UserDetailsServiceImpl类中实现UserDetailsService接口的loadUserByUsername方法。在该方法中,使用accountService.findAccountByEmail方法通过邮箱查找账户,并返回一个UserPrincipalImp实例。
class UserDetailsServiceImpl implements UserDetailsService { private AccountService accountService; public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { Account account = accountService.findAccountByEmail(email); return new UserPrincipalImp(account); } // ... }
通过以上的修改,可以解决Spring Boot 2.7.0中WebSecurityConfigurerAdapter的过时问题。
问题的出现的原因是Spring Boot的2.7.0版本中,WebSecurityConfigurerAdapter类被弃用,需要升级代码以适应新的版本。解决方法是修改WebSecurityConfig类中的方法,将原来的configure(AuthenticationManagerBuilder authenticationManagerBuilder)方法修改为authenticationManager(AuthenticationConfiguration authenticationConfiguration)方法,并将configure(HttpSecurity http)方法替换为filterChain(HttpSecurity http)方法。
具体代码如下:
import com.myproject.UrlMapping; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; (prePostEnabled = true) public class SecurityConfig { private final UserDetailsService userDetailsService; private final AuthEntryPointJwt unauthorizedHandler; private final AuthTokenFilter authenticationJwtTokenFilter; public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() .antMatchers(UrlMapping.AUTH + UrlMapping.SIGN_UP).permitAll() .antMatchers(UrlMapping.AUTH + UrlMapping.LOGIN).permitAll() .antMatchers(UrlMapping.VALIDATE_JWT).permitAll() .antMatchers("/api/test/**").permitAll() .anyRequest().authenticated(); http.addFilterBefore(authenticationJwtTokenFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedMethods("*"); } }; } }
此外,还需要在build.gradle文件中添加以下依赖:
implementation 'javax.xml.bind:jaxb-api:2.3.0'
以上就是解决Spring Boot 2.7.0版本中WebSecurityConfigurerAdapter被弃用的问题的方法。