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

WebSecurityConfigurerAdapter废弃后,如何暴露多个AuthenticationManager?

如何在无WebSecurityConfigurerAdapter的情况下暴露两个独立的AuthenticationManager(LDAP+内存认证)

核心思路

要分别创建两个独立的AuthenticationManager Bean,需为每种认证方式单独构建对应的认证提供者链,避免依赖全局的AuthenticationManager(它会自动合并所有认证源)。

1. 内存认证的实现与对应的AuthenticationManager

首先修正InMemoryUserDetailsManager的Bean定义(添加@Bean注解使其成为Spring管理的Bean),然后手动构建仅使用内存认证的AuthenticationManager:

@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
    UserDetails apiViewAll = User.builder()
            .username(ApiRolesUsers.API_VIEW_ALL)
            .password("{noop}" + apiKeyStore.getKeyByUserName(ApiRolesUsers.API_VIEW_ALL))
            .roles(ApiRolesUsers.API_VIEW_ALL)
            .build();

    UserDetails updateAll = User.builder()
            .username(ApiRolesUsers.API_UPDATE_ALL)
            .password("{noop}" + apiKeyStore.getKeyByUserName(ApiRolesUsers.API_UPDATE_ALL))
            .roles(ApiRolesUsers.API_UPDATE_ALL)
            .build();

    UserDetails edlUpdate = User.builder()
            .username(ApiRolesUsers.API_EDL_UPDATE)
            .password("{noop}" + apiKeyStore.getKeyByUserName(ApiRolesUsers.API_EDL_UPDATE))
            .roles(ApiRolesUsers.API_EDL_UPDATE)
            .build();
    
    return new InMemoryUserDetailsManager(apiViewAll, updateAll, edlUpdate);
}

@Bean(name = "apiAuthenticationManager")
public AuthenticationManager apiAuthenticationManager(InMemoryUserDetailsManager inMemoryUserDetailsManager) {
    // 创建内存认证的提供者
    DaoAuthenticationProvider inMemoryProvider = new DaoAuthenticationProvider();
    inMemoryProvider.setUserDetailsService(inMemoryUserDetailsManager);
    // 匹配代码中使用的{noop}密码编码器
    inMemoryProvider.setPasswordEncoder(NoOpPasswordEncoder.getInstance());
    
    // 构建仅包含内存认证提供者的AuthenticationManager
    return new ProviderManager(List.of(inMemoryProvider));
}

2. 保留已实现的LDAP认证AuthenticationManager

你已完成的LDAP认证Bean可以直接保留,它会作为独立的AuthenticationManager存在:

@Bean(name = "authenticationManager")
AuthenticationManager ldapAuthenticationManager(LdapContextSource contextSource) {
    LdapBindAuthenticationManagerFactory factory = 
            new LdapBindAuthenticationManagerFactory(contextSource);
    factory.setUserSearchBase(ldapUserSearchBase);
    factory.setUserSearchFilter(ldapUserSearchFilter);
    return factory.createAuthenticationManager();
}

关键说明

  • 之前调用AuthenticationConfiguration.getAuthenticationManager()返回的是全局认证管理器,它会自动收集所有注册的AuthenticationProvider(包括LDAP和内存),因此无法得到仅对应内存认证的实例。
  • 通过手动创建ProviderManager并指定单一认证提供者,能确保每个AuthenticationManager仅使用对应的认证方式,和之前WebSecurityConfigurerAdapter的行为一致。
  • 注入时可通过@Qualifier("apiAuthenticationManager")和@Qualifier("authenticationManager")分别获取两个不同的认证管理器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:06:39