
本文详解如何在 spring boot 中正确配置跨域资源共享(cors),避免手动编写过滤器导致的预检请求失败、凭据冲突及响应头缺失等问题,推荐使用官方 webmvcconfigurer 方式实现安全、可维护的跨域支持。
本文详解如何在 spring boot 中正确配置跨域资源共享(cors),避免手动编写过滤器导致的预检请求失败、凭据冲突及响应头缺失等问题,推荐使用官方 webmvcconfigurer 方式实现安全、可维护的跨域支持。
在 Spring Boot 项目中,手动实现 OncePerRequestFilter 来添加 CORS 响应头(如 Access-Control-Allow-Origin)看似直观,实则存在严重隐患:该方式无法正确处理 预检请求(Preflight OPTIONS),尤其当请求携带 Authorization 头或 credentials: true 时,浏览器会先发送 OPTIONS 请求校验权限,而自定义过滤器若未显式处理 OPTIONS 方法,将跳过后续逻辑,导致关键响应头(如 Access-Control-Allow-Origin)缺失——这正是你遇到的错误根本原因:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present
此外,你的过滤器中同时设置了 Access-Control-Allow-Origin: * 与 Access-Control-Allow-Credentials: true,这违反了 W3C CORS 规范:*当启用凭据(如 cookies、Authorization header)时,allowedOrigins 不得为通配符 ``**,否则浏览器会直接拒绝响应。
✅ 正确做法是弃用自定义过滤器,改用 Spring Boot 官方推荐的声明式配置:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/merchants/**") // 匹配具体路径(支持 Ant 风格)
.allowedOrigins("http://localhost:4200") // 显式指定可信源,禁止使用 "*"
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD")
.exposedHeaders("Authorization", "X-Total-Count") // 前端需读取的响应头
.allowCredentials(true) // 允许携带 cookie 或 token
.maxAge(3600); // 预检结果缓存时间(秒)
}
}
⚠️ 关键注意事项:
- allowedOrigins 必须为具体域名(如 "http://localhost:4200"),生产环境严禁使用 "*" 配合 allowCredentials(true);
- 路径映射建议细化(如 /api/** 或 /merchants/**),避免全局开放带来安全风险;
- 若使用 Spring Security,需确保 CORS 配置在 Security 过滤链之前生效(WebMvcConfigurer 自动优先),且 Security 配置中需显式启用 CORS:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors(Customizer.withDefaults()) // 启用 MVC 的 CORS 配置 .authorizeHttpRequests(auth -> auth .requestMatchers("/merchants/**").authenticated() // ... 其他规则 ); return http.build(); } }
总结:Spring Boot 内置的 WebMvcConfigurer#addCorsMappings 不仅自动处理预检请求、确保响应头完整性,还与 Security 模块深度集成,是安全、简洁、符合规范的最佳实践。请立即移除自定义 CorsFilter,改用上述配置,即可彻底解决带 Authorization 头时的跨域拦截问题。











