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、電話號碼等。一般會被擴展以支持業務需求。 |