Shiro系列記錄(一)—— 你真的懂Shiro麼?

1、什麼是Shiro

Shiro 是 Java 的一個安全框架,它幫助我們完成:認證、授權、加密、會話管理、與 Web 集成、緩存等。

一張圖概括基本功能點:

  • Authentication:身份認證 ,驗證用戶是否滿足登錄的條件;
  • Authorization:授權,驗證某個已認證的用戶是否擁有某個權限;
  • Session Manager:會話管理,即用戶登錄後就是一次會話,在沒有退出之前,它的所有信息都在會話中;
  • Cryptography:加密,保護數據的安全性,如密碼加密存儲到數據庫,而不是明文存儲;
  • Web Support:Web 支持,可以非常容易的集成到 Web 環境;
  • Caching:緩存,比如用戶登錄後,其用戶信息、擁有的角色 / 權限不必每次去查,這樣可以提高效率;
  • Concurrency:shiro 支持多線程應用的併發驗證,即如在一個線程中開啓另一個線程,能把權限自動傳播過去;
  • Testing:提供測試支持;
  • Run As:允許一個用戶假裝爲另一個用戶(如果他們允許)的身份進行訪問;
  • Remember Me:記住我,即一次登錄後,下次再來的話不用登錄了。

2、相關概念

這裏面試的時候喜歡問,我當初就遇到過。看一下從應用程序角度的來觀察如何使用 Shiro 完成工作:

整個流程就是:應用代碼通過 Subject 來進行認證和授權,而 Subject 又委託給 SecurityManager;我們需要給 Shiro 的 SecurityManager 注入 Realm,從而讓 SecurityManager 能得到合法的用戶及其權限進行判斷。

可以看到:應用代碼直接交互的對象是 Subject,也就是說 Shiro 的對外 API 核心就是 Subject

  • Subject:主體,代表了當前 “用戶”,這個“用戶”是一個抽象的概念,它也可以是第三方程序,大體理解爲任何與系統交互的“東西”都可以稱爲Subject。所有 Subject 都綁定到 SecurityManager,與 Subject 的所有交互都會委託給 SecurityManager;可以把 Subject 認爲是一個門面;SecurityManager 纔是實際的執行者;
  • SecurityManager:安全管理器;它管理着所有 Subject;可以看出它是 Shiro 的核心,它負責與後邊介紹的其他組件進行交互,如果學習過 SpringMVC,你可以把它看成 DispatcherServlet 前端控制器;
  • Realm:域,Shiro 從Realm 獲取安全數據(如用戶、角色、權限),就是說 SecurityManager 要驗證用戶身份,那麼它需要從 Realm 獲取相應的用戶進行比較以確定用戶身份是否合法;也需要從 Realm 得到用戶相應的角色 / 權限進行驗證用戶是否能進行操作;可以把 Realm 看成 DataSource,即安全數據源。

3、RBAC模型

RBAC是Role Based Access Control的英文縮寫,意思是基於角色的訪問控制。在RBAC模型中,who、what、how構成了訪問權限三元組,也就是“Who對What(Which)進行How的操作“。

項目中我們可以通過給用戶分配角色,給角色分配權限來實現。

4、實例解析認證與授權

在Springboot系列記錄中寫了一篇關於 SpringBoot整合Shiro實現登錄登出 的小栗子

4.1結合實例總結出身份認證的流程

  • 首先調用 Subject.login(token) 進行登錄,其會自動委託給 Security Manager,調用之前必須通過 SecurityUtils.setSecurityManager() 設置;
  • SecurityManager 負責真正的身份驗證邏輯;它會委託給 Authenticator 進行身份驗證;
  • Authenticator 纔是真正的身份驗證者,Shiro API 中核心的身份認證入口點,此處可以自定義插入自己的實現;
  • Authenticator 可能會委託給相應的 AuthenticationStrategy 進行多 Realm 身份驗證,默認 ModularRealmAuthenticator 會調用 AuthenticationStrategy 進行多 Realm 身份驗證;
  • Authenticator 會把相應的 token 傳入 Realm,從 Realm 獲取身份驗證信息,如果沒有返回 / 拋出異常表示身份驗證失敗了。此處可以配置多個 Realm,將按照相應的順序及策略進行訪問。

4.2授權

Shiro 支持三種方式的授權:

1、if/else

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
    //有權限
} else {
    //無權限
}

2、註解式:需要admin這個角色

@RequiresRoles("admin")
public void hello() {
    //有權限
}

3、頁面標籤

<shiro:hasRole name="admin">
<!— 有權限 —>
</shiro:hasRole>

授權流程

  • 先調用 Subject.isPermitted*/hasRole*接口,其會委託給 SecurityManager,而 SecurityManager 接着會委託給 Authorizer
  • Authorizer 是真正的授權者,如果我們調用如 isPermitted(“user:view”),其首先會通過 PermissionResolver 把字符串轉換成相應的 Permission 實例;
  • 在進行授權之前,其會調用相應的 Realm 獲取 Subject 相應的角色/權限用於匹配傳入的角色/權限;
  • Authorizer 會判斷 Realm 的角色/權限是否和傳入的匹配,如果有多個 Realm,會委託給 ModularRealmAuthorizer 進行循環判斷,如果匹配如 isPermitted*/hasRole* 會返回 true,否則返回 false 表示授權失敗。

以Subject.isPermitted爲例

看一下它的實現:

securityManager.isPermitted

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章