我使用的是Spring Security 4.0.1,并希望使用多个身份验证提供程序进行基于Java配置的身份验证。如何指定提供者订单?
我希望使用AuthenticationManagerBuilder,因为WebSecurityConfigurerAdapter.configureGlobal()
暴露了什么,但我没有看到任何指定顺序的方法。我是否需要手动创建ProviderManager?
更新:根据Arun的回答,这是一个问题澄清。对于自定义ActiveDirectoryLdapAuthenticationProvider
,我要使用的特定提供商为DaoAuthenticationProvider
和UserService
。
最终,我想首先针对DaoAuthenticationProvider
和ActiveDirectoryLdapAuthenticationProvider
秒进行身份验证。
AD提供商涉及对AuthenticationManagerBuilder.authenticationProvider()
的调用,但DAO提供商涉及调用AuthenticationManagerBuilder.userService()
,这会在幕后的用户服务周围创建DaoAuthenticationProvider
。查看源代码,它并没有直接将提供者放在提供者列表中(它创建了一个配置器),所以Arun的答案在这里不适合我。
我尝试手动创建DaoAuthenticationProvider
并将其传递给authenticationProvider()
。它没有影响订单。
答案 0 :(得分:1)
没有明确的订购条款。调用顺序将是您将AuthenticationProvider
提供给AuthenticationManagerBuilder.authenticationProvider()
的顺序。有关xml配置,请参阅handling SMS messages。同样适用于java配置。
例如
auth.authenticationProvider(getAuthenticationProvider2());
auth.authenticationProvider(getAuthenticationProvider1());
将导致以下调用顺序AuthenticationProvider2,AuthenticationProvider1
和
auth.authenticationProvider(getAuthenticationProvider1());
auth.authenticationProvider(getAuthenticationProvider2());
将导致以下调用顺序AuthenticationProvider1,AuthenticationProvider2
答案 1 :(得分:1)
我在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;
}
});
}
这是继续 WebSecurityConfigurerAdapter 继承类的 configure 方法。
对象后处理器的原因是我们需要等待AuthenticationManagerBuilder实际构建对象,然后才能访问和更改提供者列表的顺序。
希望它有所帮助..如果您有任何问题,请告诉我。
答案 2 :(得分:0)
我在Spring 5应用程序中遇到了完全相同的问题,但是对于我来说,创建DaoAuthenticationProvider
很有帮助。这是我的代码(我省略了很多代码,并粘贴了最重要的代码)。
...
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"));
}
}