AuthenticationManager, ProviderManager 和 AuthenticationProvider

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 的實例)
。一般
不會被擴展,除非是爲了支持某種特定類型
的認證。

UserDetails

爲了存儲一個安全實體的概況信息,包含名字、e-mail、電話號碼等。一般會被擴展以支持業務需求。

相關文章
相關標籤/搜索