SpringBoot 3.x多客户端接口权限配置异常求助
问题原因分析
Spring Security 中多个SecurityFilterChain按@Order注解的数值优先级生效,数值越小优先级越高。请求会被第一个匹配到的过滤器链处理,后续链不会再介入。你的配置核心问题是两个过滤器链都没有明确限定自身负责处理的请求范围,导致高优先级的链拦截了所有请求,低优先级的链完全不起作用:
原顺序(abcFilter1 @Order(1)在前):
abcFilter1的规则是「除了/和/health,所有请求只要认证就能访问」。由于没有限定请求范围,所有请求都会先进入这个链,只要通过认证就能访问任何接口(包括/usr/abc/1),abcFilter2根本不会被触发,所以两个客户端都能访问所有接口。调换顺序(abcFilter2 @Order(1)在前):
abcFilter2的规则是「仅/usr/abc/1允许认证访问,其他请求(除了/和/health)全部拒绝」。同样没有限定请求范围,所有请求先进入这个链,FE访问其他接口时会触发anyRequest().denyAll()被拦截,只有/usr/abc/1的请求符合规则,所以出现FE被限制的情况。
解决方案
给每个SecurityFilterChain明确指定专属的请求匹配范围,让不同请求分流到对应的链处理:
调整后的配置代码
@Bean @Order(1) // 让专属接口的链优先级更高,优先匹配 public SecurityFilterChain abcFilter2(HttpSecurity http) throws Exception { // 仅处理 /usr/abc/1 的请求 http.requestMatchers() .antMatchers("/usr/abc/1") .and() .cors(Customizer.withDefaults()).csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .apply(AadResourceServerHttpSecurityConfigurer.aadResourceServer()) .and() .authorizeHttpRequests() .requestMatchers("/usr/abc/1").authenticated() .requestMatchers("/", "/health").permitAll() .anyRequest().denyAll(); return http.build(); } @Bean @Order(2) SecurityFilterChain abcFilter1(HttpSecurity http) throws Exception { CorsConfiguration cc = new CorsConfiguration(); cc.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type")); cc.setAllowedOrigins(Arrays.asList("http://localhost:3000","example.com/")); cc.setAllowedMethods(List.of("GET", "POST","OPTIONS")); cc.setAllowCredentials(true); cc.setExposedHeaders(List.of("Authorization")); // 处理除 /usr/abc/1 之外的所有请求 http.requestMatchers() .antMatchers("/**") .antMatchers("/usr/abc/1").negate() .and() .cors(Customizer.withDefaults()).csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .apply(AadResourceServerHttpSecurityConfigurer.aadResourceServer()) .and() .authorizeHttpRequests() .requestMatchers("/", "/health").permitAll() .anyRequest().authenticated(); return http.build(); }
额外优化点
- 你的CORS配置中,
cc.setAllowedOrigins(List.of("*"))被后续的具体域名覆盖,属于冗余代码,可以直接删除。 requestMatchers()必须放在配置最前面,用于限定当前链的处理范围,否则权限规则会错误作用于所有请求。
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

