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

如何在Kotlin+Spring Boot 2.7.5中配置全局CORS?启动报错求解

Kotlin + Spring Boot 2.7.5 配置全局CORS与解决启动Bean冲突问题

问题情况

启动应用时直接报错,提示Bean重复定义:

APPLICATION FAILED TO START

描述:
无法注册类路径资源[me/xxx/xxx/config/SecurityConfiguration.class]中定义的Bean 'springSecurityFilterChain',该名称的Bean已在类路径资源[org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]中定义,且覆盖已禁用。
操作建议:
考虑重命名其中一个Bean,或通过设置spring.main.allow-bean-definition-overriding=true开启覆盖。

另外原代码里的CORS配置根本没生效——因为你在Security里禁用了CORS,后来又单独用WebMvcConfigurer配置,但Security过滤器比WebMvc的CORS处理优先级高,等于白配。

问题原因

  1. Bean冲突:原代码里重复调用authorizeRequests(),没有用链式写法,导致Spring Security生成了重复的springSecurityFilterChain Bean;
  2. CORS配置无效:先在Security里关闭CORS,又单独用WebMvc配置,Security过滤器先拦截请求,WebMvc的CORS规则根本没机会生效。

修正后的完整代码

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Profile("!test")
class SecurityConfiguration(private val issuersOAuth2Properties: IssuersOAuth2Properties) {

    @Bean
    @Throws(Exception::class)
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http
            // 配置CORS,使用自定义的配置源
            .cors { cors -> cors.configurationSource(corsConfigurationSource()) }
            .csrf { it.disable() }
            // 统一配置授权规则,链式调用避免重复
            .authorizeRequests { auth ->
                auth
                    .antMatchers(HttpMethod.OPTIONS).permitAll()
                    .antMatchers("/swagger-ui.html", "/swagger-ui/**").permitAll()
                    .antMatchers("/auth").permitAll()
                    .antMatchers("/actuator/**").permitAll()
                    .anyRequest().authenticated()
            }
            .oauth2ResourceServer { oauth2 ->
                oauth2.authenticationManagerResolver(jwtIssuerAuthManager())
            }

        return http.build()
    }

    // 定义全局CORS规则
    @Bean
    fun corsConfigurationSource(): CorsConfigurationSource {
        val corsConfig = CorsConfiguration()
        // 允许所有源,生产环境一定要改成具体的前端域名!
        corsConfig.allowedOriginPatterns = listOf("*")
        corsConfig.allowedMethods = listOf("*")
        corsConfig.allowedHeaders = listOf("*")
        corsConfig.allowCredentials = true
        corsConfig.maxAge = 3600L // 预检请求缓存时长,减少重复请求

        val source = UrlBasedCorsConfigurationSource()
        source.registerCorsConfiguration("/**", corsConfig)
        return source
    }

    @Bean
    fun jwtIssuerAuthManager(): AuthenticationManagerResolver<HttpServletRequest> {
        return JwtIssuerAuthenticationManagerResolver(IssuerManager(issuersOAuth2Properties.issuers))
    }
}

关键改动说明

  • 解决Bean冲突:把原来分散的authorizeRequests()调用合并成一次链式写法,避免Spring Security重复生成过滤器Bean;
  • CORS配置整合:直接在Security的过滤器链里配置CORS,用CorsConfigurationSource定义规则,确保请求先经过Security的CORS处理,规则生效;
  • 删除无效配置:移除了单独的WebMvcConfigurer CORS配置,不用搞两套规则,避免冲突;
  • 规范CORS设置:用allowedOriginPatterns代替旧的allowedOrigins(Spring Boot 2.4+推荐,能避免部分浏览器的CORS报错),加上maxAge提升性能。

生产环境注意点

绝对不要用"*"作为允许的源,一定要替换成你实际的前端域名(比如https://your-frontend.com),不然会有安全风险。

内容的提问来源于stack exchange,提问作者dasdsadad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:40:41