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
相关产品推荐
相关产品推荐

