You need to enable JavaScript to run this app. Spring Security多安全配置下如何让Spring托管自定义过滤器按配置隔离生效
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security多安全配置下如何让Spring托管自定义过滤器按配置隔离生效

核心问题根因
  • Spring Boot 内置自动注册规则:只要Spring容器中存在直接/间接实现javax.servlet.Filter的Bean,会自动将其挂载到Servlet容器的全局过滤器链,完全不受Spring Security配置管控,这就是你删除所有Security侧显式挂载代码后,两个自定义过滤器依然被全局触发的根本原因。
  • 你之前显式挂载时两个过滤器同时触发的原因:全局注册的过滤器会先执行一次,Security配置链里挂载的过滤器又会执行一次,相当于同一个请求被过滤器重复处理。
解决方案

第一步:禁用自定义过滤器的全局自动注册

保留过滤器上的@Component注解(保证Spring托管能力,支持@Value环境变量注入),通过FilterRegistrationBean关闭Spring Boot的自动注册逻辑,让过滤器只存在于Spring容器中、不进入全局Servlet过滤器链:
在你的WebSecurityConfig类中新增两个Bean,分别对应两个自定义过滤器:

// 关闭TestFilter1的全局自动注册
@Bean
public FilterRegistrationBean<TestFilter1> testFilter1AutoRegDisable(TestFilter1 filter1) {
    FilterRegistrationBean<TestFilter1> regBean = new FilterRegistrationBean<>(filter1);
    regBean.setEnabled(false);
    return regBean;
}

// 关闭TestFilter2的全局自动注册
@Bean
public FilterRegistrationBean<TestFilter2> testFilter2AutoRegDisable(TestFilter2 filter2) {
    FilterRegistrationBean<TestFilter2> regBean = new FilterRegistrationBean<>(filter2);
    regBean.setEnabled(false);
    return regBean;
}

第二步:为每个安全配置绑定专属过滤器

拆分的两个WebSecurityConfigurerAdapter的HttpSecurity实例是相互独立的,通过构造器注入对应专属的过滤器,在配置方法中显式挂载到当前Security过滤链即可:
修改后的完整安全配置代码:

@EnableWebSecurity(debug = true)
public class WebSecurityConfig {

    // 第一步提到的两个全局注册禁用Bean,写在这里即可
    @Bean
    public FilterRegistrationBean<TestFilter1> testFilter1AutoRegDisable(TestFilter1 filter1) {
        FilterRegistrationBean<TestFilter1> regBean = new FilterRegistrationBean<>(filter1);
        regBean.setEnabled(false);
        return regBean;
    }

    @Bean
    public FilterRegistrationBean<TestFilter2> testFilter2AutoRegDisable(TestFilter2 filter2) {
        FilterRegistrationBean<TestFilter2> regBean = new FilterRegistrationBean<>(filter2);
        regBean.setEnabled(false);
        return regBean;
    }

    @Order(1)
    @Configuration
    public static class Config1 extends WebSecurityConfigurerAdapter {
        // 构造器注入v1版本专属的TestFilter1
        private final TestFilter1 v1Filter;

        public Config1(TestFilter1 v1Filter) {
            this.v1Filter = v1Filter;
        }

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            System.out.println("******** Config1:config");
            http.antMatcher("/api/v1/**")
                    // 将专属过滤器挂载到当前Security链,位置为BasicAuthenticationFilter之前
                    .addFilterBefore(v1Filter, BasicAuthenticationFilter.class)
                    .authorizeRequests()
                    .antMatchers("/api/v1/greet").permitAll()
                    .anyRequest().authenticated();
        }
    }

    @Order(2)
    @Configuration
    public static class Config2 extends WebSecurityConfigurerAdapter {
        // 构造器注入v2版本专属的TestFilter2
        private final TestFilter2 v2Filter;

        public Config2(TestFilter2 v2Filter) {
            this.v2Filter = v2Filter;
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            System.out.println("******** Config2:config");
            http.antMatcher("/api/v2/**")
                    // 将专属过滤器挂载到当前Security链
                    .addFilterBefore(v2Filter, BasicAuthenticationFilter.class)
                    .authorizeRequests()
                    .antMatchers("/api/v2/greet").permitAll()
                    .anyRequest().authenticated();
        }
    }
}
验证效果
  • 访问/api/v1/**路径时,只会触发TestFilter1的逻辑,不会执行TestFilter2
  • 访问/api/v2/**路径时,只会触发TestFilter2的逻辑,不会执行TestFilter1
  • 两个过滤器上的@Value注入字段可以正常读取环境变量,符合Spring托管的要求
注意事项
  • 不要将同一个过滤器同时挂载到多个Security配置类中,否则会跨路径重复触发
  • 如果后续升级到Spring Security 6.x(WebSecurityConfigurerAdapter已废弃),核心逻辑不变:定义独立的SecurityFilterChain Bean,通过addFilterBefore挂载对应过滤器,同时保留FilterRegistrationBean禁用全局注册即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 12:15:03