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

如何为Spring Security过滤器配置不同的AuthenticationProvider

解决Spring Security中不同过滤器绑定对应AuthenticationProvider的问题

这个问题我之前也碰到过——默认情况下Spring Security会把所有注册的AuthenticationProvider都加到全局的AuthenticationManager里,导致你的两个过滤器都会使用这个全局管理器,自然没法做到各自只用对应的Provider。下面是亲测有效的配置方案:

1. 先注册两个Provider的Bean

首先把你的两个Provider声明为Spring Bean,方便后续注入:

@Bean
public AjaxAuthenticationProvider ajaxAuthenticationProvider() {
    return new AjaxAuthenticationProvider();
}

@Bean
public JwtAuthenticationProvider jwtAuthenticationProvider() {
    return new JwtAuthenticationProvider();
}

2. 为每个过滤器单独创建AuthenticationManager

我们需要给每个过滤器单独配置一个仅包含对应Provider的AuthenticationManager,避免全局共享:

@Bean
public AuthenticationManager ajaxAuthManager(AuthenticationManagerBuilder authBuilder) throws Exception {
    return authBuilder
            .authenticationProvider(ajaxAuthenticationProvider())
            // 注意不要调用parentAuthenticationManager(),避免继承全局配置
            .build();
}

@Bean
public AuthenticationManager jwtAuthManager(AuthenticationManagerBuilder authBuilder) throws Exception {
    return authBuilder
            .authenticationProvider(jwtAuthenticationProvider())
            .build();
}

3. 配置过滤器并绑定对应的AuthenticationManager

接下来创建过滤器实例,分别设置对应的AuthenticationManager和各自要处理的请求路径:

@Bean
public AjaxAuthenticationFilter ajaxAuthenticationFilter() throws Exception {
    AjaxAuthenticationFilter filter = new AjaxAuthenticationFilter();
    // 绑定专属的AuthenticationManager
    filter.setAuthenticationManager(ajaxAuthManager(authenticationManagerBuilder()));
    // 指定这个过滤器要处理的请求路径,比如Ajax登录接口
    filter.setFilterProcessesUrl("/login/ajax");
    return filter;
}

@Bean
public JWTAuthenticationFilter jwtAuthenticationFilter() throws Exception {
    JWTAuthenticationFilter filter = new JWTAuthenticationFilter();
    filter.setAuthenticationManager(jwtAuthManager(authenticationManagerBuilder()));
    // 指定JWT过滤器处理的路径,比如所有API请求
    filter.setFilterProcessesUrl("/api/**");
    return filter;
}

4. 将过滤器添加到Security过滤链中

最后在WebSecurityConfig的configure(HttpSecurity http)方法里,把两个过滤器加入到合适的位置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
            // 放行登录接口
            .antMatchers("/login/ajax").permitAll()
            .anyRequest().authenticated()
        .and()
        // 添加Ajax过滤器,放在UsernamePasswordAuthenticationFilter之前
        .addFilterBefore(ajaxAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        // 添加JWT过滤器,放在BasicAuthenticationFilter之前(或者你需要的位置)
        .addFilterBefore(jwtAuthenticationFilter(), BasicAuthenticationFilter.class);
}

关键原理说明

通过为每个过滤器单独构建AuthenticationManager,我们确保了每个管理器中只包含对应的AuthenticationProvider,这样当过滤器触发认证时,只会使用绑定的Provider处理请求,不会出现混淆的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:29:20