1.3 ProviderManager
ProviderManager 是的最常用的 AuthenticationManager 实现类。
ProviderManager 管理了一个 AuthenticationProvider 列表,每个 AuthenticationProvider 都是一个认证器,不同的 AuthenticationProvider 用来处理不同的 Authentication 对象的认证。一次完整的身份认证流程可能会经过多个 AuthenticationProvider。
ProviderManager 相当于代理了多个 AuthenticationProvider,他们的关系如下图:
1.4 AuthenticationProvider
AuthenticationProvider 定义了 Spring Security 中的验证逻辑,我们来看下 AuthenticationProvider 的定义:
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
boolean supports(Class<?> authentication);
}
可以看到,AuthenticationProvider 中就两个方法:
-
authenticate 方法用来做验证,就是验证用户身份。
-
supports 则用来判断当前的 AuthenticationProvider 是否支持对应的 Authentication。
在一次完整的认证中,可能包含多个 AuthenticationProvider,而这多个 AuthenticationProvider 则由 ProviderManager 进行统一管理,具体可以参考松哥之前的文章:松哥手把手带你捋一遍 Spring Security 登录流程。
这里我们来重点看一下 DaoAuthenticationProvider,因为这是我们最常用的一个,当我们使用用户名/密码登录的时候,用的就是它,DaoAuthenticationProvider 的父类是 AbstractUserDetailsAuthenticationProvider,我们就先从它的父类看起:
public abstract class AbstractUserDetailsAuthenticationProvider implements
AuthenticationProvider, InitializingBean, MessageSourceAware {
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
-
String username = (authentication.getPrincipal() == null) ? “NONE_PROVIDED”
- authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
try {
user = retrieveUser(username,
(UsernamePasswordAuthenticationToken) authentication);
}
catch (UsernameNotFoundException notFound) {
logger.debug(“User