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
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時刻
需要實現的功能:
-
demo2保留demo1的所有功能,github專案地址
-
自定義一個驗證器加入過濾器鏈(實現:當使用者使用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;
}
}
小結
- 很抱歉我依舊沒有為你講解如何將使用者、角色等資料存入資料庫中,本節更多是介紹了Spring Security的驗證流程,但相信你如果真的結合demo2學了下來,你的收穫一定不小
- 我們自定義了一個驗證器並將其加入過濾器鏈使黑客baize賬戶獲取兩個許可權並完成登陸
- 白澤將在下一篇真正開始將資料存入資料庫並構成第三個demo,敬請期待吧~
- 歡迎評論區留言