配置多个数据源
多个数据源是指在同一个系统中,用户数据来自不同的表,在认证时,如果第一张表没有查找到用户,那就去第二张表中查询,依次类推。
看了前面的分析,要实现这个需求就很容易了。认证要经过 AuthenticationProvider,每一个 AuthenticationProvider 中都配置了一个 UserDetailsService,而不同的 UserDetailsService 则可以代表不同的数据源。所以我们只需要手动配置多个 AuthenticationProvider,并为不同的 AuthenticationProvider 提供不同的 UserDetailsService 即可。
为了方便起见,这里通过 InMemoryUserDetailsManager 来提供 UserDetailsService 实例,在实际开发中,只需要将 UserDetailsService 换成自定义的即可,具体配置如下:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Primary
UserDetailsService us1() {
return new InMemoryUserDetailsManager(User.builder()
.username("javaboy").password("{noop}123").roles("admin").build());
}
@Bean
UserDetailsService us2() {
return new InMemoryUserDetailsManager(User.builder()
.username("sang").password("{noop}123").roles("user").build());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean()
throws Exception {
DaoAuthenticationProvider dao1 = new DaoAuthenticationProvider();
dao1.setUserDetailsService(us1());
DaoAuthenticationProvider dao2 = new DaoAuthenticationProvider();
dao2.setUserDetailsService(us2());
ProviderManager manager = new ProviderManager(dao1, dao2);
return manager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
//省略
}
}
首先定义了两个 UserDetailsService 实例,不同实例中存储了不同的用户;然后重写 authenticationManagerBean 方法,在该方法中,定义了两个 DaoAuthenticationProvider 实例并分别设置了不同的 UserDetailsService;最后构建 ProviderManager 实例并传入两个 DaoAuthenticationProvider。当系统进行身份认证操作时,就会遍历 ProviderManager 中不同的 DaoAuthenticationProvider,进而调用到不同的数据源。
在本书的配套案例中,笔者提供了一个基于 MyBatis 配置多数据源的案例,读者可以参考。 |