SpringBoot 3 SecurityFilterChain迁移后/services返回401求助
核心差异:permitAll() 和 ignoring() 的区别
在SpringBoot2中你用的webSecurity.ignoring()是让指定路径完全绕过Spring Security的过滤器链,不会触发任何认证、授权或其他安全检查;而SpringBoot3中改用的permitAll()只是允许该路径的访问,但请求依然会经过整个Security过滤器链,链中的其他组件(比如CSRF保护、自定义认证过滤器)可能会拦截请求导致401。
可能的具体原因及解决办法
1. CSRF保护拦截(最常见)
SpringBoot3中CSRF保护默认开启,如果你的/services/**接口是POST/PUT/DELETE等非GET请求,且请求没有携带CSRF Token,就会被拦截返回401。而/actuator/health默认是GET请求,且Spring Boot Actuator默认会忽略对健康端点的CSRF检查,所以能正常访问。
解决办法:
如果不需要对/services/**做CSRF保护,可以在配置中忽略该路径的CSRF检查:
@Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.csrf(csrf -> csrf.ignoringRequestMatchers("/services/**")) .authorizeHttpRequests(authorize -> authorize .requestMatchers("/services/**", "/actuator/health").permitAll() .anyRequest().authenticated() ); return http.build(); }
2. 路径匹配规则差异
SpringBoot3默认使用PathPatternParser作为路径匹配器,和SpringBoot2默认的AntPathMatcher在某些匹配规则上有差异(比如**的匹配范围)。如果你的请求路径和配置的/services/**匹配不上,也会触发401。
解决办法:
- 显式使用
AntPathMatcher来保持和SpringBoot2一致的匹配逻辑:@Bean public PathMatcher pathMatcher() { return new AntPathMatcher(); } - 或者在
requestMatchers中指定使用Ant风格匹配:.requestMatchers(AntPathRequestMatcher.antMatcher("/services/**"), "/actuator/health")
3. 保持和SpringBoot2一致的忽略逻辑
如果你希望完全沿用SpringBoot2的配置效果(让路径绕过整个Security过滤器链),可以改用WebSecurityCustomizer来配置忽略路径,而不是用SecurityFilterChain的permitAll():
@Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring() .requestMatchers("/actuator/health/**", "/services/**"); }
4. 存在多个SecurityFilterChain优先级冲突
如果你的项目中还有其他SecurityFilterChain Bean,优先级更高的配置可能覆盖了当前规则,导致/services/**的权限配置不生效。
解决办法:
给当前的SecurityFilterChain添加@Order注解,设置更高的优先级(数值越小优先级越高):
@Bean @Order(1) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { // 配置内容 }
内容的提问来源于stack exchange,提问作者Tom

