Spring Security环境下CORS授权预检请求错误排查求助
核心问题
你遇到的CORS错误本质是Spring Security的CORS配置未正确生效,导致预检请求(OPTIONS)的响应头里没有包含Authorization字段,而你之前通过WebMvcConfigurer配置的CORS规则被Spring Security覆盖了。另外你的配置里还有两个明显错误:
错误点拆解
allowedOrigins配置错误allowedOrigins指定的是请求源(Origin),即域名+端口,而非具体路由。你填的http://localhost:5173/login是路由,不是合法的Origin,会导致CORS规则匹配失败。Spring Security与WebMvc的CORS配置冲突
当使用Spring Security时,http.cors()默认会优先使用Security自身的CORS配置,而非WebMvcConfigurer的addCorsMappings规则,这导致你之前写的CORsConfiguration类完全没生效。自定义
CORSFilter干扰正常处理
你在Security过滤器链中添加了自定义CORSFilter,如果这个过滤器没有正确处理预检请求的响应头,会覆盖Spring Security的CORS处理逻辑,导致Access-Control-Allow-Headers不包含Authorization。
修复方案
步骤1:删除无效的CORsConfiguration类
保留Spring Security层面的CORS配置即可,避免冲突。
步骤2:配置Spring Security的CORS源
创建CorsConfigurationSource Bean,让http.cors()直接使用这个配置:
@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 允许携带凭证(对应前端withCredentials=true) config.setAllowCredentials(true); // 仅允许React应用的源 config.setAllowedOrigins(List.of("http://localhost:5173")); // 允许的请求头,必须包含Authorization config.setAllowedHeaders(List.of( "Authorization", "Cache-Control", "Content-Type", "Accept", "X-Requested-With", "Origin" )); // 暴露给前端的响应头(如果前端需要读取Authorization等头) config.setExposedHeaders(List.of( "Authorization", "Cache-Control", "Content-Type" )); // 允许的HTTP方法 config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有接口生效 source.registerCorsConfiguration("/**", config); return source; }
步骤3:修正SecurityFilterChain配置
去掉自定义的CORSFilter,让Security使用上面的CORS配置:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()); // 其他安全规则(如认证、授权)可以在这里添加 return http.build(); }
步骤4:前端配合设置
如果使用Axios,需要开启携带凭证:
axios.defaults.withCredentials = true;
额外说明
- 如果你需要打印请求头验证令牌,可以改用Spring的
HandlerInterceptor或普通的Filter,只做日志打印,不要修改响应头,避免干扰CORS处理。 - 当
allowCredentials(true)时,allowedOrigins不能用*,必须指定具体的源,否则浏览器会拒绝接受响应。
内容的提问来源于stack exchange,提问作者JDS

