Spring Boot带Authorization头请求遇CORS跨域问题求助
问题分析
不带Authorization头的请求能正常跨域,带该头时触发预检OPTIONS请求失败,核心原因是:
- 带自定义请求头的请求会触发浏览器发送OPTIONS预检请求,用于确认服务器是否允许该跨域请求
- 当前过滤器没有直接处理OPTIONS请求,而是直接传递到后续过滤器链(比如Spring Security的认证过滤器),导致预检请求被拦截,没有返回
Access-Control-Allow-Origin等必要头
解决方案
1. 修改CORS过滤器,直接处理OPTIONS预检请求
在过滤器中先判断请求方法是否为OPTIONS,如果是,直接设置响应状态码为200并返回,无需走后续业务过滤器链:
package com.kompan.security.filter; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class CorsFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD"); response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization"); response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Authorization"); response.addHeader("Access-Control-Allow-Credentials", "true"); response.addIntHeader("Access-Control-Max-Age", 10); // 直接处理OPTIONS预检请求,返回200状态码 if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } }
2. 若使用Spring Security,需允许OPTIONS请求通过
如果项目中集成了Spring Security,需要在Security配置类中添加规则,允许OPTIONS请求无需认证:
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.http.HttpMethod; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // 允许所有OPTIONS请求 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .anyRequest().authenticated() .and() // 其他认证/授权配置... } }
关键说明
- OPTIONS预检请求是浏览器自动发送的,不需要携带Authorization头,所以不能用认证过滤器去拦截它
- 处理OPTIONS请求时直接返回200,确保浏览器能拿到完整的CORS响应头,从而允许后续的实际请求(带Authorization头)发送
内容的提问来源于stack exchange,提问作者Karol Wolny
相关产品推荐
相关产品推荐

