天天看點

Shiro簡介及認證授權過程

1、是什麼?

Apache Shiro 是一個強大而靈活的開源安全架構,它幹淨利落地處理身份認證,授權,企業會話管理和加密

2、能幹嘛?

1)驗證使用者來核實他們的身份

2)對使用者執行通路控制,如:

     判斷使用者是否被配置設定了一個确定的安全角色

     判斷使用者和是否被允許做某事

3)在任何環境下使用session API,即使沒有web或ejb容器

4)在身份驗證,通路控制期間或在會話的生命周期,對事件作出反應

5)聚集一個或多個使用者安全資料的資料源,并作為一個單一的複合使用者“視圖”

6)啟用單點登入(SSO)功能

7)為沒有關聯到登入的使用者啟用"Remember Me"服務

3、什麼是權限管理?

權限管理是系統的安全範疇,要求必須是合法的使用者才可以通路系統(使用者認證),且必須具有該 資源的通路權限才可以通路該 資源(授權)。

認證:對使用者合法身份的校驗,要求必須是合法的使用者才可以通路系統。

授權:通路控制,必須具有該 資源的通路權限才可以通路該 資源。

權限模型:标準權限資料模型包括 :使用者、角色、權限(包括資源和權限)、使用者角色關系、角色權限關系。

權限配置設定:通過UI界面友善給使用者配置設定權限,對上邊權限模型進行增、删、改、查操作。

權限控制:

       基于角色的權限控制:根據角色判斷是否有操作權限,因為角色的變化 性較高,如果角色修改需要修改控制代碼,系統可擴充性不強。

       基于資源的權限控制:根據資源權限判斷是否有操作權限,因為資源較為固定,如果角色修改或角色中權限修改不需要修改控制代碼,使用此方法系統可維護性很強。建議使用。

權限管理的解決方案:

    對于粗顆粒權限管理:建議在系統架構層面去解決,寫系統架構級别統一代碼(基礎代碼)。

    粗顆粒權限:比如對系統的url、菜單、jsp頁面、頁面上按鈕、類方法進行權限管理,即對資源類型進行權限管理。

    對于細顆粒權限管理:

    細顆粒權限:比如使用者id為001的使用者資訊(資源執行個體)、類型為01的商品資訊(資源執行個體),對資源執行個體進行權限管理,了解對資料級别的權限管理。

    細顆粒權限管理是系統的業務邏輯,業務邏輯代碼不友善抽取統一代碼,建議在系統業務層進行處理。

4、shiro相關概念簡介:

Subject:

    Subject即主體,外部應用與subject進行互動,subject記錄了目前操作使用者,将使用者的概念了解為目前操作的主體,可能是一個通過覽器請求的使用者,也可能是一個運作的程式。    

    Subject在shiro中是一個接口,接口中定義了很多認證授權相關的方法,外部程式通過subject進行認證授,而subject是通過SecurityManager安全管理器進行認證授權

SecurityManager:

     SecurityManager即安全管理器,對全部的subject進行安全管理,它是shiro的核心,負責對所有的subject進行安全管理。通過SecurityManager可以完成subject的認證、授權等,實質上SecurityManager是通過Authenticator進行認證,通過Authorizer進行授權,通過SessionManager

進行會話管理等。

     SecurityManager是一個接口,繼承了Authenticator, Authorizer, SessionManager這三個接口。

Authenticator:

     Authenticator即認證器,對使用者身份進行認證,Authenticator是一個接口,shiro提供ModularRealmAuthenticator實作類,通過ModularRealmAuthenticator基本上可以滿足大多數需求,也可以自定義認證器。

Authorizer:

     Authorizer即授權器,使用者通過認證器認證通過,在通路功能時需要通過授權器判斷使用者是否有此功能的操作權限。

realm:

Realm即領域,相當于datasource資料源,securityManager進行安全認證需要通過Realm擷取使用者權限資料,比如:如果使用者身份資料在資料庫那麼realm就需要從資料庫擷取使用者身份資訊。

     注意:不要把realm了解成隻是從資料源取資料,在realm中還有認證授權校驗的相關的代碼。

sessionManager:

sessionManager即會話管理,shiro架構定義了一套會話管理,它不依賴web容器的session,是以shiro可以使用在非web應用上,也可以将分布式應用的會話集中在一點管理,此特性可使它實作單點登入。

SessionDAO:

SessionDAO即會話dao,是對session會話操作的一套接口,比如要将session存儲到資料庫,可以通過jdbc将會話存儲到資料庫。

CacheManager:

CacheManager即緩存管理,将使用者權限資料存儲在緩存,這樣可以提高性能。

Cryptography:

Cryptography即密碼管理,shiro提供了一套加密/解密的元件,友善開發。比如提供常用的散列、加/解密等功能。

5、shiro認證執行流程

1)subject(主體)請求認證,調用subject.login(token),token中包含了使用者登入的賬号和密碼。由securityManager通過Authenticator(接口)進行認證

2)Authenticator最終由實作類ModularRealmAuthenticator調用Realm(同時向Realm傳入了包含使用者資訊的token)資料庫中擷取使用者真實的賬号和密碼。這裡的Realm為自定義的。

3)Realm先根據token中的賬号去資料庫中查找該使用者資訊(包括賬号和密碼):

如果找不到則給ModularRealmAuthenticator傳回null

如果找到則給ModularRealmAuthenticator傳回使用者資訊(包括賬号和密碼)。

4)ModularRealmAuthenticator接收Realm傳回的Anthentication認證資訊:

如果傳回的資訊為null,ModularRealmAuthenticator則抛出異常(UnknownAccountException--賬号不存在)

如果傳回的資訊不為null,說明使用者是存在的。ModularRealmAuthenticator再對Realm傳回的使用者密碼(根據傳回的使用者得到該使用者密碼)與token中的密碼進行對比。如果密碼一緻則認證通過;如果密碼不一緻則抛出異常(IncorrectCredentialsException--密碼錯誤)

UnknownAccountException

賬号不存在異常如下:(Realm幹的活)

org.apache.shiro.authc.UnknownAccountException: No account found for user。。。。

IncorrectCredentialsException

當輸入密碼錯誤(賬号存在)會抛此異常,如下:(ModularRealmAuthenticator幹的活)

org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - zhangsan, rememberMe=false] did not match the expected credentials.

更多如下:

DisabledAccountException(帳号被禁用)

LockedAccountException(帳号被鎖定)

ExcessiveAttemptsException(登入失敗次數過多)

ExpiredCredentialsException(憑證過期)等

6、shiro授權的執行流程

1)對subject進行授權,調用方法isPermitted("permission串")

2)SecurityManager執行授權,最終通過ModularRealmAuthorizer執行授權

3)ModularRealmAuthorizer執行Realm(自定義的Realm)從資料庫查詢權限資料調用realm的授權方法:doGetAuthorizationInfo

4)Realm從資料庫查詢權限資料,傳回ModularRealmAuthorizer授權資訊

5)ModularRealmAuthorizer調用PermissionResolver進行權限串比對

6、如果比對後,isPermitted中"permission串"在realm從資料庫中查詢到權限資料中,說明使用者通路permission串有權限,否則 沒有權限,抛出異常。

繼續閱讀