AuthenticationManager是一个接口:安全
public interface AuthenticationManager { Authentication authenticate(Authentication authentication) throws AuthenticationException; }
ProviderManager是AuthenticationManager的实现类:ide
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。spa
接下来咱们看一下整个的认证过程:code
认证是经过AuthenticationManager的authenticate函数实现的。也就是经过AuthenticationManager实现类ProviderManager的authenticate函数认证,ProviderManager的authenticate函数会轮训ProviderManager的List<AuthenticationProvider> providers成员变量,若是该providers中若是有一个AuthenticationProvider的supports函数返回true,那么就会调用该AuthenticationProvider的authenticate函数认证,若是认证成功则整个认证过程结束。若是不成功,则继续使用下一个合适的AuthenticationProvider进行认证,只要有一个认证成功则为认证成功。blog
若是上述过程没有认证成功,且该ProviderManager的成员变量AuthenticationManager parent不为null,那么会使用该parent继续认证。通常不会用到该AuthenticationManager parent,稍微留意如下便可。接口
另:Authenticationip
能够看到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; }
另:DaoAuthenticationProviderci
<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 | 为了存储一个安全实体的概况信息,包含名字、e-mail、电话号码等。一般会被扩展以支持业务需求。 |