Spring Security配置permitAll的DELETE接口返回401,其余放行接口正常
问题根因
两个配置问题叠加,刚好形成了「GET类放行接口正常、DELETE类放行接口返回401」的特殊现象:
- 默认开启的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状态,很容易误以为是授权规则配置不生效。
- 拆分两个独立
authorizeRequests配置块的写法存在逻辑隐患- 虽然当前Spring Security版本下,多次调用
authorizeRequests()不会清空之前配置的匹配规则,但这种写法完全违背了Spring Security的链式配置设计逻辑:URL匹配规则是从上到下顺序执行的,拆分两个配置块的写法很容易在后续维护中出现规则顺序错乱,最终导致授权规则不生效。
- 虽然当前Spring Security版本下,多次调用
修复方案
- 针对CSRF拦截问题,根据业务场景选择处理方式:
- 对于基于JWT鉴权的无状态前后端分离接口,完全不需要CSRF防护,可直接在配置链路中关闭CSRF校验。
- 如果需要保留CSRF防护,可针对需要放行的接口单独配置CSRF忽略规则,或在请求中携带合法的CSRF token。
- 将所有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
相关产品推荐
相关产品推荐

