You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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继承,改用SecurityFilterChain Bean配置HTTP安全规则
  • 使用Kotlin DSL替代原链式调用(更符合Kotlin语法习惯)
  • 用requestMatchers替代antMatchers(Spring Security 6.0推荐用法,功能一致)
  • 显式定义AuthenticationManager Bean,替代原重写configure(AuthenticationManagerBuilder)的方式
  • 调整DaoAuthenticationProvider的属性赋值为Kotlin风格的属性访问(替代setter方法)

报错解决方法

DeferredSecurityContext类在Spring Security 6.0中已被移除,出现该报错的原因及解决方式:

  1. 依赖版本不兼容

    • 确保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查看依赖树,排除冲突的旧版本依赖)
  2. 第三方依赖引入旧类

    • 若项目中使用了其他依赖(如某些权限框架、自定义扩展),检查其是否依赖了旧版本的Spring Security,需升级该依赖至兼容Spring Security 6.0的版本,或手动排除其中的Spring Security依赖

内容的提问来源于stack exchange,提问作者Saher Al-Sous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 05:55:30