You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security与Angular 5集成时POST请求无法正常工作问题

解决Spring REST + Angular5 POST请求403(CORS过滤器失效)问题

看起来你的核心问题是浏览器发送的POST请求触发了预检OPTIONS请求,但这个请求被Spring Security拦截了,导致CORS头没有正确返回,最终POST请求被浏览器判定为跨域违规而返回403。GET请求属于简单请求不需要预检,所以能正常响应,这完全符合你描述的现象。

下面是几个针对性的解决方案,按推荐优先级排序:

方案1:使用Spring内置的CORS配置(推荐)

手动写CORS过滤器很容易踩顺序和预检请求处理的坑,Spring已经提供了更完善的CORS支持,结合Spring Security配置一起用更可靠:

第一步:配置全局CORS规则

创建WebMvc配置类,定义允许的跨域规则:

@Configuration
public class WebCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 对所有接口生效
                .allowedOrigins("*") // 允许所有来源,生产环境建议指定具体域名
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Content-Type", "x-requested-with")
                .maxAge(48000); // 预检请求缓存时间
    }
}

第二步:在Spring Security中启用CORS并放行OPTIONS请求

修改你的Security配置类,确保CORS规则生效,并且让预检OPTIONS请求直接通过:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and() // 启用Spring Security的CORS支持,自动应用全局规则
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS预检请求
            .anyRequest().authenticated() // 其他请求需要授权
            // 这里添加你的其他Security配置,比如表单登录、JWT认证等
            .and()
            .csrf().disable(); // 前后端分离场景下通常需要禁用CSRF,或配置CSRF令牌传递
    }
}

方案2:修复自定义CORS过滤器

如果你坚持使用自己写的过滤器,需要解决两个关键问题:

  1. 让过滤器在Spring Security过滤器之前执行
  2. 直接处理OPTIONS请求,不要让它进入后续的Security校验链

修改你的过滤器类:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 确保这个过滤器是第一个执行的
public class CustomCorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        // 设置CORS响应头
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type,x-requested-with");
        response.addHeader("Access-Control-Max-Age", "48000");

        // 处理预检OPTIONS请求:直接返回200,不需要走后续过滤器链
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void destroy() {}
}

同时,在Spring Security配置中也要放行OPTIONS请求,避免Security提前拦截:

// 加入Security配置的configure方法中
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

关键原因分析

  • 预检请求拦截:POST请求(尤其是带Content-Type这类非简单头的)会触发浏览器发送OPTIONS预检请求,Spring Security默认会拦截所有未授权的请求,包括OPTIONS,导致CORS头无法返回,浏览器拒绝后续POST请求。
  • 过滤器顺序问题:如果你的自定义CORS过滤器在Spring Security过滤器之后执行,那么Security已经返回403了,CORS头根本没机会被添加到响应中。

内容的提问来源于stack exchange,提问作者Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:51:31