Spring Security 6多SecurityFilterChains异常:仅单个链被调用
Spring Security 6 多SecurityFilterChain配置问题修复
问题根源在于你没给每个SecurityFilterChain指定专属的路径处理范围。Spring Security会按@Order顺序依次检查链,第一个链如果没限定路径,会接管所有请求——哪怕请求路径本应属于后面的链。比如Basic Auth链排第一时,/v1/transaction/**请求会进入这个链,但没有Basic Auth凭证就返回401;反过来OAuth2链排第一时,/v1/info请求没有JWT也会被拦截。
修复方案:给每个链添加securityMatcher
通过securityMatcher明确每个链负责的路径,Spring Security就会根据请求路径自动匹配对应的链,不再按顺序强制接管所有请求。
修改后的Basic Auth配置类
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) @EnableWebSecurity @Configuration public class BasicAuthSecurity { public AuthenticationManager authProviderManager() { // 省略代码 } @Bean @Order(1) public SecurityFilterChain basicAuthSecurityFilterChain(HttpSecurity http) throws Exception { return http // 仅处理指定路径的POST请求 .securityMatcher(HttpMethod.POST, "/v1/info", "/v1/info/{user}") .authenticationManager(authProviderManager()) .authorizeHttpRequests(authorize -> authorize .anyRequest().hasRole("user") ) .httpBasic(withDefaults()) .build(); } }
修改后的OAuth2配置类
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) @EnableWebSecurity @Configuration public class Oauth2Security { @Bean @Order(2) public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception { return http // 仅处理指定路径的POST请求 .securityMatcher(HttpMethod.POST, "/v1/transaction/**") .authorizeHttpRequests(authorize -> authorize .anyRequest().hasAnyRole("poweruser", "admin") ) .oauth2ResourceServer(oauth2 -> oauth2.jwt()) .build(); } }
补充说明
securityMatcher是Spring Security 6中用来限定链处理范围的核心配置,替代了旧版本的antMatcher/mvcMatcher。- 请求到达时,Spring Security会逐个检查链的
securityMatcher,匹配到第一个符合条件的链就用它处理,不会再往下执行其他链。 - 去掉原配置中
.anyRequest().authenticated()的宽泛规则,因为securityMatcher已经限定了路径,直接对匹配路径设置权限即可,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Rox
相关产品推荐
相关产品推荐

