AuthenticationManager是一个接口:
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
ProviderManager是AuthenticationManager的实现类:
public class ProviderManager implements AuthenticationManager, MessageSourceAware,
InitializingBean { ...... private List<AuthenticationProvider> providers = Collections.emptyList(); ...... public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
......
}
}
从以上代码中可以看到ProviderManager有一个List<AuthenticationProvider> providers成员变量。AuthenticationProvider也是一个接口:
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
boolean supports(Class<?> authentication);
}
可以看到包含两个成员函数authenticate和supports。
接下来我们看一下整个的认证过程:
认证是通过AuthenticationManager的authenticate函数实现的。也就是通过AuthenticationManager实现类ProviderManager的authenticate函数认证,ProviderManager的authenticate函数会轮训ProviderManager的List<AuthenticationProvider> providers成员变量,如果该providers中如果有一个AuthenticationProvider的supports函数返回true,那么就会调用该AuthenticationProvider的authenticate函数认证,如果认证成功则整个认证过程结束。如果不成功,则继续使用下一个合适的AuthenticationProvider进行认证,只要有一个认证成功则为认证成功。
如果上述过程没有认证成功,且该ProviderManager的成员变量AuthenticationManager parent不为null,那么会使用该parent继续认证。一般不会用到该AuthenticationManager parent,稍微留意以下即可。
另:Authentication
可以看到authenticate函数返回Authentication,Authentication是一个接口,通过该接口可以获得用户相信信息,代码:
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
另:DaoAuthenticationProvider
<authentication-provider>默认实例化AuthenticationProvider的一个实现:DaoAuthenticationProvider。DaoAuthenticationProvider通过接口UserDetailsService的实现类从内存或DB中获取用户信息UserDetails(UserDetails十分类似Authentication,也是一个接口,但是与Authentication用途不同,不要搞混)。DaoAuthenticationProvider通过函数authenticate比较入参authentication与UserDetails是否相符,来判断用户是否可以登录。如果相符,会将获得的UserDetails中的信息补全到一个Authentication实现类,并将该实现类作为认证实体返回。以后便可以通过当前上下文的认证实体Authentication获取当前登录用户的信息。
UserDetails代码:
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
UserDetails和Authentication区别:
接口 | 目的 |
Authentication | 它存储安全实体的标识、密码以及认证请求 |
UserDetails | 为了存储一个安全实体的概况信息,包含名 |