Spring Security極簡入門三部曲(中篇)


Spring Security極簡入門三部曲(中篇)

大家好,我是白澤。通過上篇的學習,我們實現了一個簡單的基於角色驗證的小demo,但是不足之處在於用戶和角色的信息我們寫死在了內存中,而實際項目中必然是寫在數據庫里的,但是在將數據存入數據庫之前,為了讓你更深入理解Spring Security授權的驗證流程,我需要為你介紹一些關鍵的接口和類(很遺憾這一部分無法完全避免),如果你只想繼續學習Spring Security的使用,直接跳到demo時刻部分吧!

驗證流程

Authentication接口

用戶在前端輸入的登陸信息傳入后台后將封裝入一個Authentication接口的實現類,它作為認證和授權的對象穿過整個過濾器鏈,反過來我們也能從Authentication實現類中取出用戶賬戶的相關信息(用戶名、密碼、獲取的權限等) Authentication實現類的獲取方法:SecurityContextHolder.getContext().getAuthentication()

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();//返回一組已經分發的權限(角色)

    Object getCredentials();	//返回憑證,即密碼

    Object getDetails();		

    Object getPrincipal();		//返回身份信息,即用戶名

    boolean isAuthenticated();

    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

過濾器鏈

Spring Security框架核心有一個ProviderManager類,點開它的源碼,它有一個List providers屬性,這個List集合中就是存放着一個個AuthenticationProvider的實現類(定義了一個個權限驗證的規則),這個List集合就組成了過濾器鏈

AuthenticationProvider接口:

public interface AuthenticationProvider {
    Authentication authenticate(Authentication var1) throws AuthenticationException;

    boolean supports(Class<?> var1);
}

上面提到,ProviderManager實例的providers屬性存放了AuthenticationProvider接口的實現類集合,而AuthenticationProvider實現類就是實現權限驗證流程的關鍵,它主要需要實現AuthenticationProvider接口的authenticate()方法,這個方法接收一個Authentication實例,返回一個Authentication實例

結合上面那張ProviderManager的圖,你是不是就理解過濾器鏈是如何工作的了?(一開始就提到了用戶登陸之后,將數據封裝為一個Authentication實例,並由這個實例通過整個過濾器鏈進行驗證,而此時AuthenticationProvider接口的實現類的authenticate()方法不就實現了接收一個Authentication實例,返回一個Authentication實例嗎?一個個AuthenticationProvider實現類組合在一起就得到了鏈式的驗證流程

demo時刻

需要實現的功能:

  1. demo2保留demo1的所有功能,github項目地址

  2. 自定義一個驗證器加入過濾器鏈(實現:當用戶使用baize賬戶登陸時,無論密碼是什么,都將獲取USER和ADMIN權限)

代碼講解

事實上我們只新建了AuthenticationProvider接口的實現類BaiZeAuthenticationProvider,去重寫它的兩個方法,自定義了一個驗證器。並在SecurityConfiguration類中完成注入(相當於自定義過濾器加入過濾器鏈)

@Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //從authentication實例中獲取用戶名和密碼(這個authentication實例貫穿流程始終)
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();
        if (username.equals("baize")) {
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));  //ROLE_ADMIN寫法是固定的
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));   //ROLE_USER寫法是固定的
            return new UsernamePasswordAuthenticationToken(username, password, authorities);
        } else {
            return null;
        }
    }

小結

  1. 很抱歉我依舊沒有為你講解如何將用戶、角色等數據存入數據庫中,本節更多是介紹了Spring Security的驗證流程,但相信你如果真的結合demo2學了下來,你的收獲一定不小
  2. 我們自定義了一個驗證器並將其加入過濾器鏈使黑客baize賬戶獲取兩個權限並完成登陸
  3. 白澤將在下一篇真正開始將數據存入數據庫並構成第三個demo,敬請期待吧~
  4. 歡迎評論區留言


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM