Java 使用AuthenticationManagerBuilder的提供程序订单
我正在使用SpringSecurity4.0.1,并希望使用多个身份验证提供程序来使用基于Java的配置进行身份验证。如何指定提供程序顺序 我希望使用,因为这是Java 使用AuthenticationManagerBuilder的提供程序订单,java,spring,authentication,spring-security,Java,Spring,Authentication,Spring Security,我正在使用SpringSecurity4.0.1,并希望使用多个身份验证提供程序来使用基于Java的配置进行身份验证。如何指定提供程序顺序 我希望使用,因为这是websecurityConfigureAdapter.configureGlobal()公开的内容,但我看不到任何指定顺序的方法。我是否需要手动创建一个文件 更新:根据阿伦的回答,这里有一个问题澄清。我要使用的特定提供程序是自定义用户服务的ActiveDirectoryLdapAuthenticationProvider和DAAuthe
websecurityConfigureAdapter.configureGlobal()
公开的内容,但我看不到任何指定顺序的方法。我是否需要手动创建一个文件
更新:根据阿伦的回答,这里有一个问题澄清。我要使用的特定提供程序是自定义用户服务的ActiveDirectoryLdapAuthenticationProvider
和DAAuthenticationProvider
最后,我想首先对DaoAuthenticationProvider
进行身份验证,然后对activedirectoryldapaauthenticationprovider
进行身份验证
AD提供程序涉及调用AuthenticationManagerBuilder.authenticationProvider()
,但DAO提供程序涉及调用AuthenticationManagerBuilder.userService()
,这将在后台用户服务周围创建一个DAOAAuthenticationProvider
。看看源代码,它没有直接将提供者放在提供者列表中(它创建了一个配置器),因此Arun的答案在这里对我不起作用
我尝试手动创建DaoAuthenticationProvider
,并将其传递给authenticationProvider()
。它没有影响订单。没有明确的订购规定。调用顺序将是您向AuthenticationManagerBuilder.AuthenticationProvider()提供AuthenticationProvider
的顺序。请参阅xml配置。这同样适用于java配置
例如
auth.authenticationProvider(getAuthenticationProvider2());
auth.authenticationProvider(getAuthenticationProvider1());
将导致以下调用顺序AuthenticationProvider2,AuthenticationProvider1
及
将导致以下调用顺序AuthenticationProvider1,AuthenticationProvider2
我在configure方法中尝试了objectPostProcessor,它成功了。不确定这是否是您想要的:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(new BCryptPasswordEncoder());
auth.authenticationProvider(new CustomAuthenticationProvider(this.dataSource));
auth.objectPostProcessor(new ObjectPostProcessor<Object>() {
@Override
public <O> O postProcess(O object) {
ProviderManager providerManager = (ProviderManager) object;
Collections.swap(providerManager.getProviders(), 0, 1);
return object;
}
});
}
@覆盖
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.jdbccauthentication().dataSource(dataSource)
.passwordEncoder(新的BCryptPasswordEncoder());
auth.authenticationProvider(新的CustomAuthenticationProvider(this.dataSource));
auth.objectPostProcessor(新的objectPostProcessor(){
@凌驾
公共O后处理(O对象){
ProviderManager ProviderManager=(ProviderManager)对象;
swap(providerManager.getProviders(),0,1);
返回对象;
}
});
}
这是WebSecurity ConfigureAdapter继承类上的配置方法
使用对象后处理器的原因是,我们需要等待AuthenticationManagerBuilder实际构建对象,然后才能访问和更改提供者列表的顺序
希望能有帮助。。如果您有任何问题,请告诉我。我在Spring 5应用程序中遇到了完全相同的问题,但在我的情况下,创建DaoAuthenticationProvider
有帮助。这是我的代码(我省略了很多,粘贴了最重要的代码)
谢谢你,阿伦。我查看了代码,可以看出这对AuthenticationProviders是有效的,我们显式地通过authenticationProvider()方法,因此+1是有效的。但我正试图让它与用户服务一起工作。我会相应地更新问题。我可以看看您的spring安全配置代码吗?我想了解身份验证提供程序是如何配置的。当您使用authenticationManagerBuilder.ldapaauthentication()
(当ldap位于最后一个位置,并且您不能强制它位于自定义身份验证提供程序之前)时,它可以工作,也可以应用它
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(new BCryptPasswordEncoder());
auth.authenticationProvider(new CustomAuthenticationProvider(this.dataSource));
auth.objectPostProcessor(new ObjectPostProcessor<Object>() {
@Override
public <O> O postProcess(O object) {
ProviderManager providerManager = (ProviderManager) object;
Collections.swap(providerManager.getProviders(), 0, 1);
return object;
}
});
}
...
import javax.annotation.PostConstruct;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder.authenticationProvider(userDetailsAuthenticationProvider());
if (isSsoEnabled()) {
authenticationManagerBuilder
.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
if (isKerberosEnabled()) {
authenticationManagerBuilder
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
@Bean
public DaoAuthenticationProvider userDetailsAuthenticationProvider() {
DaoAuthenticationProvider authProvider
= new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new CustomPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
...
}
private JWTConfigurer securityConfigurerAdapter() {
return new JWTConfigurer(tokenProvider);
}
private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider =
new ActiveDirectoryLdapAuthenticationProvider(getAdDomain(), getAdServer());
provider.setUserDetailsContextMapper((UserDetailsContextMapper) userDetailsService);
return provider;
}
private boolean isSsoEnabled() {
return Boolean.parseBoolean(ConfigurationFileUtils.getConfigurationProperty("security.use-sso"));
}
private boolean isKerberosEnabled() {
return isSsoEnabled() && Boolean.parseBoolean(ConfigurationFileUtils.getConfigurationProperty("security.use-kerberos"));
}
}