正文

有三种情况我们需要配置多个AuthenticationProvider,甚至是自定义AuthenticationProvider:

  1. 用户认证信息存储在多个地方
  2. 在同一个地方但是需要多种授权方式,比如说手机号+密码可以登录,邮箱+密码也可以登录
  3. 以上两种情况都有
    配置AuthenticationProvider,可以通过AuthenticationManagerBuilder,或者注册一个AuthenticationManager的bean,Spring Security Configurer这块相当灵活,充分了解设计架构之后,还有很多其他的方式。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource1;

@Autowired
@Qualifier("secondaryDataSource")
private DataSource dataSource2;

@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/favicon.ico");
}

/**
* 只有这种方法可以配置多个DaoAuthenticationProvider,不然AuthenticationManagerConfiguration就会起作用,详细原因看AuthenticationManagerConfiguration类上的文档。
*
*/
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {

JdbcUserDetailsManager jdbcUserDetailsManager1 = new JdbcUserDetailsManager();
jdbcUserDetailsManager1.setDataSource(dataSource1);
DaoAuthenticationProvider authenticationProvider1 = new DaoAuthenticationProvider();
authenticationProvider1.setUserDetailsService(jdbcUserDetailsManager1);

JdbcUserDetailsManager jdbcUserDetailsManager2 = new JdbcUserDetailsManager();
jdbcUserDetailsManager2.setDataSource(dataSource2);
DaoAuthenticationProvider authenticationProvider2 = new DaoAuthenticationProvider();
authenticationProvider2.setUserDetailsService(jdbcUserDetailsManager2);

ProviderManager authenticationManager = new ProviderManager(
Arrays.asList(authenticationProvider1, authenticationProvider2));
return authenticationManager;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().httpBasic().disable().anonymous().disable().authorizeRequests().anyRequest()
.authenticated();
}
}

注意

经测试在AuthenticationManagerBuilder 进行如下的设置是不行的:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource1).and().jdbcAuthentication().dataSource(dataSource2);
}

原因参考AuthenticationManagerConfiguration这个类的文档。