You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多SecurityFilterChain中hasAuthority("ADMIN")权限校验失效问题

问题根源

Spring Security 中多个SecurityFilterChain是按@Order注解的数值从小到大顺序执行的,第一个匹配到当前请求的FilterChain会完全处理该请求,后续FilterChain不会再介入。

你遇到的问题核心在于:

  • 优先级更高的apiKeyFilterChain(@Order(1))中配置了requestMatchers("/admin/**").permitAll(),所有/admin/notification/**这类请求会被第一个FilterChain直接放行,根本不会流转到jwtFilterChain(@Order(2))执行权限校验。
  • 你在ApiKeyAuthFilter中配置的shouldNotFilter只是让过滤器不执行,但FilterChain的授权规则已经生效,请求依然会被第一个FilterChain允许访问。
解决方案

需要给两个FilterChain明确划分各自负责的路径范围,确保需要JWT权限校验的路径不会被第一个FilterChain提前处理。

1. 修改apiKeyFilterChain,限定仅处理需要API Key验证的路径

假设你的API Key仅用于/external/**这类外部接口(根据实际业务调整),修改后代码如下:

@Bean
@Order(1)
public SecurityFilterChain apiKeyFilterChain(HttpSecurity http) throws Exception {
    http
            // 明确指定此FilterChain仅处理的路径
            .requestMatchers(matchers -> matchers.antMatchers("/external/**"))
            .csrf(AbstractHttpConfigurer::disable)
            .cors(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                    .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(apiKeyAuthFilter, UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

2. 调整jwtFilterChain,明确处理剩余路径并保留权限规则

@Bean
@Order(2)
public SecurityFilterChain jwtFilterChain(HttpSecurity http) throws Exception {
    http
            // 指定此FilterChain处理的路径范围
            .requestMatchers(matchers -> matchers
                    .antMatchers("/admin/**", "/auth/**", "/clients/**")
            )
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers(new AntPathRequestMatcher("/admin/notification/**")).hasAuthority("ADMIN")
                    .requestMatchers(new AntPathRequestMatcher("/auth/**")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/clients/**")).permitAll()
                    .requestMatchers(new AntPathRequestMatcher("/admin/**")).authenticated()
                    .anyRequest().authenticated()
            )
            .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

3. 可选:移除ApiKeyAuthFilter中的排除路径逻辑

现在FilterChain已经明确划分了路径范围,ApiKeyAuthFilter只会在/external/**路径下执行,无需再通过shouldNotFilter排除其他路径,可以删除这部分代码。

内容的提问来源于stack exchange,提问作者yhab shaker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:57:14