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

Spring Security配置双AuthenticationProvider:如何定义内存认证提供者

Spring Security 配置双认证提供者(内存认证+Waffle Windows认证)

问题背景

需要为Spring Security配置两个认证提供者:一个是通过Waffle实现的Windows登录认证(WindowsAuthenticationProvider),另一个是内存用户认证。当前配置中无法正确定义并引用内存认证的inMemoryAuthenticationProvider对象,导致配置报错。

解决方案

你不需要手动创建inMemoryAuthenticationProvider对象,Spring Security会自动为内存用户配置生成对应的认证提供者。只需合并认证配置,并调整HttpSecurity的配置逻辑即可。

方式一:简洁配置(推荐)

将内存用户配置和Waffle认证提供者统一注册到AuthenticationManagerBuilder中,Spring会自动管理所有认证提供者,无需手动指定:

@Configuration
@EnableWebSecurity
public class WaffleConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private WindowsAuthenticationProvider windowsAuthProvider;

    @Autowired
    private NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint;

    @Autowired
    private NegotiateSecurityFilter negotiateSecurityFilter;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置内存认证用户
        GrantedAuthority readAuthority = () -> "eligibilite:read";
        GrantedAuthority writeAuthority = () -> "eligibilite:write";

        auth.inMemoryAuthentication()
                .withUser("francois")
                .password("{noop}fournel")
                .authorities(readAuthority)
                .and()
                .withUser("francois2")
                .password("{noop}fournel2")
                .authorities(writeAuthority);

        // 添加Waffle的Windows认证提供者
        auth.authenticationProvider(windowsAuthProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                // REST接口使用Basic认证,自动匹配内存用户
                .antMatcher("/api/**")
                .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                // Spring MVC页面使用Waffle Windows认证
                .and()
                .antMatcher("/secure/**")
                .authorizeRequests()
                .antMatchers("/secure/**").authenticated()
                .and()
                .authenticationEntryPoint(negotiateSecurityFilterEntryPoint)
                .addFilterBefore(negotiateSecurityFilter, BasicAuthenticationFilter.class);
    }
}

方式二:手动创建内存认证提供者(灵活控制)

如果需要对内存认证提供者做更细粒度的自定义,也可以手动创建对应的Bean:

@Configuration
@EnableWebSecurity
public class WaffleConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private WindowsAuthenticationProvider windowsAuthProvider;

    @Autowired
    private NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint;

    @Autowired
    private NegotiateSecurityFilter negotiateSecurityFilter;

    // 手动创建内存认证提供者Bean
    @Bean
    public AuthenticationProvider inMemoryAuthenticationProvider() {
        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
        
        // 定义权限和用户
        UserDetails francois = User.withUsername("francois")
                .password("{noop}fournel")
                .authorities("eligibilite:read")
                .build();
        UserDetails francois2 = User.withUsername("francois2")
                .password("{noop}fournel2")
                .authorities("eligibilite:write")
                .build();
                
        userDetailsManager.createUser(francois);
        userDetailsManager.createUser(francois2);

        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsManager);
        return provider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 注册手动创建的内存认证提供者
        auth.authenticationProvider(inMemoryAuthenticationProvider());
        // 注册Waffle认证提供者
        auth.authenticationProvider(windowsAuthProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                // REST接口指定使用内存认证提供者
                .antMatcher("/api/**")
                .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .and()
                .authenticationProvider(inMemoryAuthenticationProvider())
                .httpBasic()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                // Spring MVC页面使用Waffle认证
                .and()
                .antMatcher("/secure/**")
                .authorizeRequests()
                .antMatchers("/secure/**").authenticated()
                .and()
                .authenticationProvider(windowsAuthProvider)
                .authenticationEntryPoint(negotiateSecurityFilterEntryPoint)
                .addFilterBefore(negotiateSecurityFilter, BasicAuthenticationFilter.class);
    }
}

关键说明

  • 当使用auth.inMemoryAuthentication()时,Spring Security会自动生成DaoAuthenticationProvider实例,无需手动定义。
  • 合并configure(AuthenticationManagerBuilder)方法,避免多个配置方法导致的覆盖问题。
  • 方式二适合需要自定义内存认证逻辑(比如密码编码器、用户详情服务)的场景,方式一更适合简单场景。

内容的提问来源于stack exchange,提问作者François F.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:05:19