如何在使用SecurityFilterChain的Spring Boot应用中配置CORS?
正确配置Spring Security + CORS的解决方案
你的问题在于同时使用了Spring Security的CORS过滤器和WebMvc的CORS配置,两者机制独立且Security过滤器优先级更高,导致WebMvc的配置未生效。以下是正确的配置方式:
步骤1:移除WebMvcConfigurer的CORS配置
删除你定义的corsConfigurer() Bean,避免与Security的CORS配置冲突。
步骤2:创建Spring Security专用的CorsConfigurationSource Bean
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource; import java.util.Arrays; import java.util.Collections; @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 注意:去掉origin末尾的斜杠,否则会导致匹配失败 config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // 允许的HTTP方法 config.setAllowedMethods(Arrays.asList("GET", "OPTIONS", "POST")); // 允许的请求头:添加Content-Type,POST请求通常需要这个头 config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type")); // 允许携带凭证(比如Cookie、JWT) config.setAllowCredentials(true); // 如果前端需要读取响应头中的自定义字段,这里需要暴露出来 config.setExposedHeaders(Collections.singletonList("Authorization")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有路径应用该CORS配置 source.registerCorsConfiguration("/**", config); return source; }
步骤3:在SecurityFilterChain中关联CORS配置
修改你的Security配置,将自定义的CorsConfigurationSource绑定到cors()方法中:
JWTAuthenticationFilter jwtAuthenticationFilter = new JWTAuthenticationFilter(); jwtAuthenticationFilter.setAuthenticationManager(authManager); jwtAuthenticationFilter.setFilterProcessesUrl("/login"); return http // 关联自定义的CORS配置源 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf().disable() .authorizeHttpRequests(auth -> auth // 显式放行OPTIONS预检请求,避免被认证拦截 .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .anyRequest().authenticated() ) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilter(jwtAuthenticationFilter) .addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class) .build();
关键注意事项
- Origin末尾不要加斜杠:
http://localhost:3000/会被视为与http://localhost:3000不同的源,导致CORS校验失败。 - 允许必要的请求头:如果你的请求包含
Content-Type(比如JSON格式的POST请求),必须将其加入allowedHeaders,否则预检请求会被拒绝。 - 放行OPTIONS请求:虽然Spring Security的CORS配置会自动处理预检请求,但显式配置
permitAll可以避免因其他规则导致的拦截。 - 不要混用两套CORS配置:Spring Security和WebMvc的CORS是独立的,当使用SecurityFilterChain时,优先使用Security的CORS配置即可。
内容的提问来源于stack exchange,提问作者Sebastian Perez
相关产品推荐
相关产品推荐

