Spring Security 5.3迁移至6.0的Kotlin配置问题及报错解决
Spring Security 5.3 Kotlin配置迁移至6.0版本的解决方案
问题背景
原Spring Security 5.3版本基于WebSecurityConfigurerAdapter的Kotlin配置,迁移至6.0版本时遇到适配问题,参考官方文档后仍无法解决,频繁出现以下报错:
Caused by: java.lang.ClassNotFoundException: org.springframework.security.core.context.DeferredSecurityContext
原配置代码如下:
@Configuration @EnableWebSecurity class WebSecurityConfiguration : WebSecurityConfigurerAdapter() { @Autowired lateinit var service: UserService /** * Will be resolved into: WebSecurityEntryPoint injected instance. */ @Autowired lateinit var unauthorizedHandler: AuthenticationEntryPoint @Autowired lateinit var successHandler: WebSecurityAuthSuccessHandler @Autowired override fun configure(auth: AuthenticationManagerBuilder) { auth.authenticationProvider(authenticationProvider()) } override fun configure(http: HttpSecurity?) { http ?.csrf()?.disable() ?.exceptionHandling() ?.authenticationEntryPoint(unauthorizedHandler) ?.and() ?.authorizeRequests() /** * Access to Notes and Todos API calls is given to any authenticated system user. */ ?.antMatchers("/notes")?.authenticated() ?.antMatchers("/notes/**")?.authenticated() ?.antMatchers("/todos")?.authenticated() ?.antMatchers("/todos/**")?.authenticated() /** * Access to User API calls is given only to Admin user. */ ?.antMatchers("/users")?.hasAnyAuthority("ADMIN") ?.antMatchers("/users/**")?.hasAnyAuthority("ADMIN") ?.and() ?.formLogin() ?.successHandler(successHandler) ?.failureHandler(SimpleUrlAuthenticationFailureHandler()) ?.and() ?.logout() } @Bean fun authenticationProvider(): DaoAuthenticationProvider { val authProvider = DaoAuthenticationProvider() authProvider.setUserDetailsService(service) authProvider.setPasswordEncoder(encoder()) return authProvider } @Bean fun encoder(): PasswordEncoder = BCryptPasswordEncoder(11) @Bean fun accessDecisionManager(): AccessDecisionManager { val decisionVoters = Arrays.asList( WebExpressionVoter(), RoleVoter(), AuthenticatedVoter() ) return UnanimousBased(decisionVoters) } }
适配Spring Security 6.0的Kotlin配置方案
Spring Security 6.0移除了WebSecurityConfigurerAdapter,改用基于Bean的配置方式,以下是迁移后的代码:
@Configuration @EnableWebSecurity class WebSecurityConfiguration { @Autowired lateinit var service: UserService @Autowired lateinit var unauthorizedHandler: AuthenticationEntryPoint @Autowired lateinit var successHandler: WebSecurityAuthSuccessHandler // 配置SecurityFilterChain替代原configure(HttpSecurity)方法 @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { http .csrf { it.disable() } .exceptionHandling { it.authenticationEntryPoint(unauthorizedHandler) } .authorizeHttpRequests { auth -> auth // 配置接口权限规则 .requestMatchers("/notes/**", "/todos/**").authenticated() .requestMatchers("/users/**").hasAnyAuthority("ADMIN") // 设置自定义访问决策管理器 .accessDecisionManager(accessDecisionManager()) // 其他请求默认允许(根据实际需求调整) .anyRequest().permitAll() } .formLogin { form -> form .successHandler(successHandler) .failureHandler(SimpleUrlAuthenticationFailureHandler()) } .logout { /* 可根据需求配置logout相关参数 */ } return http.build() } // 配置AuthenticationManager @Bean fun authenticationManager(authManagerBuilder: AuthenticationManagerBuilder): AuthenticationManager { authManagerBuilder.authenticationProvider(authenticationProvider()) return authManagerBuilder.build() } @Bean fun authenticationProvider(): DaoAuthenticationProvider { val authProvider = DaoAuthenticationProvider() authProvider.userDetailsService = service authProvider.passwordEncoder = encoder() return authProvider } @Bean fun encoder(): PasswordEncoder = BCryptPasswordEncoder(11) @Bean fun accessDecisionManager(): AccessDecisionManager { val decisionVoters = listOf( WebExpressionVoter(), RoleVoter(), AuthenticatedVoter() ) return UnanimousBased(decisionVoters) } }
关键变更说明
- 移除
WebSecurityConfigurerAdapter继承,改用SecurityFilterChainBean配置HTTP安全规则 - 使用Kotlin DSL替代原链式调用(更符合Kotlin语法习惯)
- 用
requestMatchers替代antMatchers(Spring Security 6.0推荐用法,功能一致) - 显式定义
AuthenticationManagerBean,替代原重写configure(AuthenticationManagerBuilder)的方式 - 调整
DaoAuthenticationProvider的属性赋值为Kotlin风格的属性访问(替代setter方法)
报错解决方法
DeferredSecurityContext类在Spring Security 6.0中已被移除,出现该报错的原因及解决方式:
依赖版本不兼容
- 确保Spring Boot版本与Spring Security版本匹配:Spring Boot 3.x对应Spring Security 6.x,若使用Spring Boot 2.x则最高只能用Spring Security 5.x
- 检查所有依赖,确保没有引入旧版本的Spring Security相关JAR包(可通过
./gradlew dependencies或mvn dependency:tree查看依赖树,排除冲突的旧版本依赖)
第三方依赖引入旧类
- 若项目中使用了其他依赖(如某些权限框架、自定义扩展),检查其是否依赖了旧版本的Spring Security,需升级该依赖至兼容Spring Security 6.0的版本,或手动排除其中的Spring Security依赖
内容的提问来源于stack exchange,提问作者Saher Al-Sous
相关产品推荐
相关产品推荐

