Spring Boot3+与Spring Security6+实现SecurityFilterChain时遇CORS错误
Spring Boot 3 + Spring Security 6 CORS问题解决方案
核心问题排查与修复
1. 启用Spring Security的CORS配置
你的SecurityFilterChain中显式调用了.cors().disable(),直接禁用了Spring Security的CORS支持,导致定义好的corsConfigurationSource完全不生效。修改这部分代码:
原代码片段:
.cors().disable() //.configurationSource(corsConfigurationSource()) // .and()
替换为:
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
2. 修正AllowedOrigins的URL格式
当前配置的允许来源末尾带有斜杠(比如http://localhost:8080/),会导致浏览器发送的Origin(通常不带末尾斜杠)匹配失败,需要去掉末尾斜杠:
configuration.setAllowedOrigins(Arrays.asList( "http://localhost:8080", "http://localhost:4200", "http://localhost:5174", "你的服务器自定义URL" ));
3. 放行CORS预检OPTIONS请求
浏览器发送的CORS预检请求(OPTIONS方法)不需要携带Authorization,必须被无条件放行。在authorizeHttpRequests中添加规则:
.authorizeHttpRequests((authz) -> authz .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS请求 .requestMatchers(HttpMethod.GET, AUTH_WHITELIST).permitAll())
4. 调整自定义过滤器逻辑
确保自定义过滤器不会拦截OPTIONS请求,在过滤器开头添加判断:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 直接放行OPTIONS预检请求 if (HttpMethod.OPTIONS.name().equals(request.getMethod())) { response.setHeader("Access-Control-Max-Age", "1728000"); filterChain.doFilter(request, response); return; } Enumeration<String> headerToken = request.getHeaders(AUTH_HEADER_NAME); // 补充判断是否有元素,避免空指针 if (headerToken == null || !headerToken.hasMoreElements()) { this.logger.trace("No Authorization header found!"); filterChain.doFilter(request, response); return; } // 执行原有认证逻辑 authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); response.addHeader("Access-Control-Expose-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range"); SecurityContextHolder.getContext().setAuthentication(authToken); filterChain.doFilter(request, response); }
5. 简化AllowedHeaders配置(可选)
当前AllowedHeaders配置过于冗余,可简化为仅保留必要请求头:
configuration.setAllowedHeaders(Arrays.asList( HttpHeaders.AUTHORIZATION, HttpHeaders.CONTENT_TYPE, HttpHeaders.ORIGIN, "X-Requested-With" ));
验证步骤
- 重启应用
- 在浏览器发起请求,检查控制台CORS错误是否消失
- 查看浏览器网络请求的响应头,确认包含
Access-Control-Allow-Origin、Access-Control-Allow-Credentials等必要CORS头
内容的提问来源于stack exchange,提问作者Rajeev Kashyap
相关产品推荐
相关产品推荐

