多数据源配置
467字约2分钟
2024-08-08
实现多个 UserDetailsService 报错分析
如果我们直接实现多个 UserDetailsService,启动项目之后去访问登录则会显示 No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken

我们可以看下 UserDetailsService
Bean
初始化相关的内容,在类 InitializeUserDetailsManagerConfigurer
中可以看到,如果有多个 UserDetailService
存在,则不会给全局的 AuthenticationManager
设置 AuthenticationProvider
,因为他是一个 provider
对应一个 UserDetailService
,现在我们想要两组,所以我们就需要自己定义 AuthenticationManager

配置多数据源
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
</dependencies>
IndexController(登录成功后访问的接口)
/**
* @ClassName IndexController
* @Desciption 首页控制层
* @Author MaRui
* @Date 2023/8/10 18:00
* @Version 1.0
*/
@RestController
public class IndexController {
/**
* 从 SecurityContextHolder 获取信息
* @return
*/
@GetMapping(value = "/")
public String index() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return JSON.toJSONString(authentication);
}
}
多个 UserDetailsService
实现,这里直接固定判断用户名称返回结果
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (!"marui".equals(username)) {
throw new UsernameNotFoundException(username);
}
UserDetails userDetails = User.withUsername("marui").password("{noop}1234").roles("admin").build();
return userDetails;
}
}
@Service
public class UserDetailService2Impl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (!"marui2".equals(username)) {
throw new UsernameNotFoundException(username);
}
UserDetails userDetails = User.withUsername("marui2").password("{noop}1234").roles("admin").build();
return userDetails;
}
}
SecurityConfig
中配置 AuthenticationManager
/**
* @ClassName SecurityConfig
* @Desciption Security 配置
* @Author MaRui
* @Date 2023/9/18 17:29
* @Version 1.0
*/
@Configuration
public class SecurityConfig {
@Bean
public AuthenticationManager authenticationManager(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(new UserDetailServiceImpl());
DaoAuthenticationProvider provider2 = new DaoAuthenticationProvider();
provider2.setUserDetailsService(new UserDetailService2Impl());
return new ProviderManager(provider2,provider);
}
}
验证一下,访问登录页面 http://127.0.0.1:8080/login,输入账号 marui
,密码 1234

登录成功,返回了获取到的当前用户信息
