You need to enable JavaScript to run this app. Spring Security配置permitAll的DELETE接口返回401,其余放行接口正常
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security配置permitAll的DELETE接口返回401,其余放行接口正常

问题根因

两个配置问题叠加,刚好形成了「GET类放行接口正常、DELETE类放行接口返回401」的特殊现象:

  1. 默认开启的CSRF防护在授权逻辑之前拦截了DELETE请求
    • Spring Security默认启用CSRF跨站请求伪造防护,该过滤器会拦截所有非安全HTTP方法的请求(包含DELETE、POST、PUT、PATCH),这类请求必须携带合法的CSRF校验token才能通过校验,无token的请求根本不会进入后续的URL授权规则匹配流程。
    • 你配置放行的/v2/api-docs是GET请求,属于CSRF防护的默认放行范围,能正常走到授权匹配环节,匹配到permitAll规则后即可正常访问。
    • 因为你配置了OAuth2 JWT资源服务器,所有未通过安全校验的请求都会被资源服务器统一返回401未授权状态,你看不到原生CSRF拦截的403状态,很容易误以为是授权规则配置不生效。
  2. 拆分两个独立authorizeRequests配置块的写法存在逻辑隐患
    • 虽然当前Spring Security版本下,多次调用authorizeRequests()不会清空之前配置的匹配规则,但这种写法完全违背了Spring Security的链式配置设计逻辑:URL匹配规则是从上到下顺序执行的,拆分两个配置块的写法很容易在后续维护中出现规则顺序错乱,最终导致授权规则不生效。

修复方案

  1. 针对CSRF拦截问题,根据业务场景选择处理方式:
    • 对于基于JWT鉴权的无状态前后端分离接口,完全不需要CSRF防护,可直接在配置链路中关闭CSRF校验。
    • 如果需要保留CSRF防护,可针对需要放行的接口单独配置CSRF忽略规则,或在请求中携带合法的CSRF token。
  2. 将所有URL授权匹配规则合并到同一个authorizeRequests配置块中,保证规则顺序清晰,避免配置混乱。修改后的配置参考:
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
            .and()
        // 无状态JWT场景直接关闭CSRF防护
        .csrf().disable()
            .and()
        // 所有授权规则统一在同一个块内配置
        .authorizeRequests()
            .antMatchers(HttpMethod.DELETE, "/v1/billingaccount/*").permitAll()
            .antMatchers("/actuator/**").permitAll()
            .antMatchers("/v2/api-docs").permitAll()
            // anyRequest规则必须放在所有匹配规则的最后
            .anyRequest().authenticated()
            .and()
        .oauth2ResourceServer().jwt()
            .jwtAuthenticationConverter(jwtAuthenticationConverter());
}

注意:所有antMatchers规则必须按照从精准到宽泛的顺序排列,anyRequest()规则必须放在所有匹配规则的最后,否则会出现规则提前匹配、后续配置失效的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 10:27:03