Spring应用间歇性CORS错误:编辑WebSecurityCustomizer后时隐时现
解决Spring REST应用Flutter Web端CORS异常问题
你的问题核心在于Spring Security的过滤器执行顺序优先于WebMvc的CORS处理,导致预检请求(OPTIONS)被认证拦截,同时部分端点偶尔报错的情况也和配置加载顺序有关。以下是具体的修复方案:
修复步骤
1. 调整SecurityFilterChain配置,添加CORS支持并放行预检请求
修改securityFilterChain方法,加入CORS配置,同时允许所有OPTIONS请求无需认证(浏览器会先发OPTIONS预检请求,此时还未携带Token):
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 配置CORS .cors(cors -> cors.configurationSource(corsConfigurationSource())) .authorizeHttpRequests((authorize) -> authorize // 放行所有OPTIONS预检请求 .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) .addFilterAfter(createPolicyEnforcerFilter(), BearerTokenAuthenticationFilter.class); return http.build(); }
2. 添加CORS配置源Bean
创建CorsConfigurationSource Bean,替代原来的WebMvc CORS配置(因为Security会优先使用这个配置):
@Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); // 允许所有前端域名(生产环境建议指定具体域名) configuration.setAllowedOrigins(Collections.singletonList("*")); // 允许所有HTTP方法 configuration.setAllowedMethods(Collections.singletonList("*")); // 允许所有请求头 configuration.setAllowedHeaders(Collections.singletonList("*")); // 如果需要携带Cookie或认证信息,开启此选项(根据你的业务需求调整) configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有路径应用CORS配置 source.registerCorsConfiguration("/**", configuration); return source; }
3. 移除冗余的WebMvc CORS配置
可以删除原来的corsConfigurer Bean,因为现在Security已经处理了CORS,避免配置冲突:
// 移除这个Bean /* @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedMethods("*") .allowedOrigins("*"); } }; } */
问题原因说明
- CORS预检请求被拦截:浏览器发送跨域请求前会先发OPTIONS预检请求,你的原配置中
anyRequest().authenticated()会要求该请求携带Token,导致返回401,触发CORS错误。 - Security优先级高于WebMvc:WebMvc的CORS配置只有在请求通过Security过滤后才会生效,无法处理被Security拦截的预检请求。
- 偶尔报错的情况:这是Spring上下文加载时过滤器顺序不稳定导致的,重启后上下文重新初始化,过滤器顺序恢复正常,所以问题暂时消失,本质还是配置缺失。
额外注意事项
- 生产环境不要使用
allowedOrigins("*"),建议指定具体的前端域名(比如https://your-flutter-app.com),提升安全性。 - 如果你的业务需要携带认证Cookie,确保
setAllowCredentials(true),同时前端请求要设置withCredentials: true(Flutter Web中对应HttpClient的withCredentials属性)。
内容的提问来源于stack exchange,提问作者VirtualPaper
相关产品推荐
相关产品推荐

