Spring Boot(Kotlin)与Angular开发时CORS预检失败求助
问题分析与解决方案
核心问题点
- 原CORS配置仅设置路径映射,未明确指定允许的请求源、方法、请求头及凭证携带权限,无法满足浏览器预检请求要求。
SecurityConfig中重复启用httpBasic(),与之前的httpBasic().disable()冲突,干扰CORS配置生效。- 自定义
AuthTokenFilter可能拦截了OPTIONS预检请求,未做放行处理。 CorsConfig错误添加@EnableWebMvc,覆盖Spring Boot默认WebMvc自动配置,导致CORS规则不生效。
修正后的配置方案
1. 重新定义CORS配置类
移除@EnableWebMvc,使用CorsConfigurationSource Bean明确配置CORS规则:
@Configuration class CorsConfig { @Bean fun corsConfigurationSource(): CorsConfigurationSource { val corsConfig = CorsConfiguration() // 替换为你的Angular前端开发地址(如http://localhost:4200) corsConfig.addAllowedOrigin("http://localhost:4200") corsConfig.addAllowedMethod("*") corsConfig.addAllowedHeader("*") corsConfig.allowCredentials = true corsConfig.maxAge = 3600L // 缓存预检请求结果,减少重复OPTIONS请求 val source = UrlBasedCorsConfigurationSource() source.registerCorsConfiguration("/**", corsConfig) return source } }
2. 修正SecurityConfig配置
移除重复的httpBasic(),绑定自定义CORS配置源并明确放行OPTIONS请求:
@EnableWebSecurity @Configuration class SecurityConfig @Autowired constructor( private val authTokenFilter: AuthTokenFilter, private val corsConfigurationSource: CorsConfigurationSource ){ @Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { http .httpBasic().disable() .csrf().disable() // 指定使用自定义CORS配置 .cors { it.configurationSource(corsConfigurationSource) } .authorizeRequests { auth -> auth .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行预检请求 .anyRequest().permitAll() } // 将Token过滤器放在认证过滤器前执行 http.addFilterBefore(authTokenFilter, UsernamePasswordAuthenticationFilter::class.java) return http.build() } }
3. 确保AuthTokenFilter放行OPTIONS请求
在自定义过滤器中添加判断,直接放行OPTIONS预检请求:
override fun doFilterInternal( request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain ) { // 直接放行OPTIONS请求 if (HttpMethod.OPTIONS.name == request.method) { response.status = HttpServletResponse.SC_OK filterChain.doFilter(request, response) return } // 你的Token校验逻辑... super.doFilterInternal(request, response, filterChain) }
开发环境临时禁用CORS(不推荐生产使用)
如果只是开发阶段临时测试,可添加全局Filter强制允许所有跨域请求:
@Configuration class DisableCorsFilter { @Bean fun corsFilter(): Filter { return Filter { request, response, chain -> val res = response as HttpServletResponse res.setHeader("Access-Control-Allow-Origin", "*") res.setHeader("Access-Control-Allow-Methods", "*") res.setHeader("Access-Control-Allow-Headers", "*") res.setHeader("Access-Control-Max-Age", "3600") if (HttpMethod.OPTIONS.name == request.method) { res.status = HttpServletResponse.SC_OK } else { chain.doFilter(request, response) } } } }
内容的提问来源于stack exchange,提问作者Hadestructhor
相关产品推荐
相关产品推荐

