shiro概念(轉)

Shiro 是一個強大而靈活的開源安全框架,可以很是清晰的處理認證、受權、管理會話以及密碼加密。以下是它所具備的特色:html

  1. 易於理解的 Java Security API;web

  2. 簡單的身份認證(登陸),支持多種數據源(LDAP,JDBC,Kerberos,ActiveDirectory 等);apache

  3. 對角色的簡單的籤權(訪問控制),支持細粒度的籤權;緩存

  4. 支持一級緩存,以提高應用程序的性能;安全

  5. 內置的基於 POJO 企業會話管理,適用於 Web 以及非 Web 的環境;session

  6. 異構客戶端會話訪問;架構

  7. 很是簡單的加密 API;框架

  8. 不跟任何的框架或者容器捆綁,能夠獨立運行。工具

首先,咱們來看看的 Shiro 的總體架構,見下圖:性能


圖 1. 總體架構

圖 1. 總體架構

 

從上圖能夠看出,Shiro 主要有四個組件:

  1. SecurityManager

    典型的 Facade,Shiro 經過它對外提供安全管理的各類服務。

  2. Authenticator

    對「Who are you ?」進行覈實。一般涉及用戶名和密碼。

    這個組件負責收集 principals 和 credentials,並將它們提交給應用系統。若是提交的 credentials 跟應用系統中提供的 credentials 吻合,就可以繼續訪問,不然須要從新提交 principals 和 credentials,或者直接終止訪問。

  3. Authorizer

    身份份驗證經過後,由這個組件對登陸人員進行訪問控制的篩查,好比「who can do what」, 或者「who can do which actions」。Shiro 採用「基於 Realm」的方法,即用戶(又稱 Subject)、用戶組、角色和 permission 的聚合體。

  4. Session Manager

    這個組件保證了異構客戶端的訪問,配置簡單。它是基於 POJO/J2SE 的,不跟任何的客戶端或者協議綁定。

圖 2. 安全模型

圖 2. 安全模型

 

上圖中,涉及了 Shiro 的五個概念:

  • Subject 是安全領域術語,除了表明人,它還能夠是應用。在單應用中,可將其視爲 User 的同義詞。

  • Principal 是 Subject 的標識,通常狀況下是惟一標識,好比用戶名。

  • Role 和 Permission 分別表明了不一樣粒度的權限,從上圖中能夠看出 Role 的粒度更大些,Permission 表明了系統的原子權限,好比數據的修改、刪除權限。對於簡單的權限應用,能夠不須要 Permission。

  • Realm 是一個執行者,負責真正的認證和鑑權。

實現應用的安全模塊的關鍵在於:定義合適的 role 和 permission,這就須要遵循以下原則:

  1. role 沒有實質內容,只是表明一組 permission,目的是爲了管理的方便,通常都是動態定義;

  2. permission 通常都是預先定義好的,不容許動態改變,除非源代碼改動,它纔會變化,它是整個安全模塊的基礎;

  3. 要使 permission 也能動態定義,並不是不可能,可是這將使鑑權很是複雜,甚至可能致使鑑權語句遍及整個程序,得不償失;

  4. 固然有一個例外:若是知道 permission 動態定義的規則和鑑權規則,如 Grails 的 fileter 中「${controllerName}:${actionName}:${params.id}」也可實現 permission 的動態定義

圖 3. 關鍵類

圖 3. 關鍵類

 

AuthenticationToken 和 AuthenticationInfo

前者在認證前使用,描述認證所需的信息,最經常使用的就是 username 和 password 對;後者在認證後使用,內容同前,可是表示已經通過認證的信息。

RememberMe

表明的是一種可能狀態,並不表示該 Subject 已經通過了認證。對於一些普通的操做,這種可能狀態並沒有大礙,但一旦涉及安全敏感的操做,必須通過認證。

Credentials 和 CredentialsMatcher

Credentials 是 Subject 的證書,在認證時使用,最經常使用的就是 password。在一般狀況下,爲了安全起見,Subject 的 credentials 都須要加密保存,因而 CredentialsMatcher 的做用就體現出來了,見下圖:

圖 4. CredentialsMatcher 的做用

這裏 CredentialsMatcher 須要將加密後的證書跟用戶登陸時提供的證書進行比對,完成認證的過程。

PAM= Pluggable Authentication Modules

在有多個 Realm 的時候使用。由認證策略決定認證結果,即 PAM= Relams + 認證策略。通常的策略有 3 種:AllSuccessful、AtLeastOneSuccessful 和 FirstSuccessful。

AuthorizationInfo

能夠當作是 Role + Permission 的組合體。

PermissionResolver 和 Permission

它們之間的關係以下:

圖 5. PermissionResolver 和 Permission 的關係

在 Shiro 中,權限被轉化爲一種字符串描述(字符串分級表示,稱之爲 WildcardPermission),從而將權限轉化爲相似於對象 equals 的操做(Shiro 中的 implies 方法)。

內置的權限有 2 個:

  • AllPermission,老是返回 true

  • WildcardPermission,權限字符串的表示方式。

WildcardPermission 是 Shiro 的精妙之處,咱們能夠將權限表示成字符串,這樣對權限的控制能夠不拘泥於物理存儲,好比對 messagge 類具備修改和刪除權限能夠標識爲:message:update,delete:*,其中‘ * ’表示全部;第一級分隔符爲‘ : ’;第二級分隔符爲‘ , ’,而對於權限字符串的解釋徹底能夠由應用本身來定。

若是要比較權限字符串,可使用 permission1.implies(permission2),它分別比較對應位置的字符串,在以下狀況中,結果會返回 true:

  • permission1 中的子串有 * 或 permission1 子串 ==permission2 子串;

  • permission1 無子串,permission2 有;

  • permission1 有子串,permission2 無,permission1 的全部子串都是 *。

總的說來,Shiro 中的 Permission 須要注意以下內容:

  1. 權限的比較實際是字符串的比較,只不過是考慮到了字符串的分級

  2. 字符串的分級劃分徹底由使用者本身決定,Shiro 的慣例是 3 級:資源 : 操做 : 實例。

  3. 字符串的使用必須一致,分隔符之間不要有空格,避免無心間引入的不一致。如:定義使用「file : create, update : 1」,而驗證使用「file : update」,那麼分解以後一個是「 update 」,一個是「 update」,因空格而引發不等。

Realm

這是一個實際訪問安全實體的組件,通常是應用相關的,跟數據源的關係是 1-1。它負責完成認證和鑑權,getAuthenticationInfo 表明了 login 的嘗試,鑑權方法則由 Authorizer 繼承而來。此處也體現了 Shiro 代碼的另外一個特色,經過繼承來擴充功能。以經常使用的 JdbcRealm 爲例,其繼承鏈以下:

圖 6. JdbcRealm 的繼承鏈

Session

它關聯一個 Subject 的上下文,其做用相似於在 HttpSession 中保存用戶標識,session 一旦過時,則從新登陸。Shiro 的 Session 是獨立的,其目的是作到環境無關性。爲了利用 Web 環境中,Shiro 實現了一個直接使用 HttpSession 的 WebSession。

SecurityManager

這是一個 Façade 接口,=Authenticator + Authorizer + SessionFactory。在總體框架圖中已經看到了它在 Shiro 中所處的位置。其特色同 Realm,同樣是使用繼承不斷地擴充功能。對於 Web 應用通常使用 DefaultWebSecurityManager。

Filter

在 Web 環境下使用 filter 進行認證和權限檢查是毋庸置疑的,而 Shiro 的特色則在於由一個主 Filter 將一羣子 filter 串起來:

圖 7. Filter 的做用

在實際使用時,須注意:

  1. web.xml 中只需配置 org.apache.shiro.web.servlet.ShiroFilter和EnvironmentLoaderListener。對於 Spring 應用,則使用 DelegatingFilterProxy;

  2. 子 filter 做爲主 filter 的配置參數值出現,特色是:順序相關

    1. 對於多個 URL,驗證順序是由上至下,相似 Exception 的匹配。所以,使用順序應該是由細到粗。

    2. 對於同一 URL,子 filter 的驗證順序是從左至右的 AND 操做。

  3. 若是配置值中含有分隔符,如 Permission,就須要使用引號來轉義。

Subject

subject 表明了一個用戶的狀態和操做,它提供了全部安全相關的操做,包括認證和籤權。能夠將其視爲另外一種形式的 Façade。缺省實現是將這些操做委派給其內部包含的 SecurityManager。

Configuration

configuration 負責將全部這些組件串起來,最終建立 SecurityManager。在 Shiro 中,缺省格式是 ini。整個配置關係以下圖:

圖 8. 配置關係

  • JSecurityFilter 建立 Configuration 實例,並將 ini 參數值傳給 Configuation。在 Spring 環境中,分別使用 SpringJSecurityFilter 和 SpringIniWebConfiguration。

  • Configuration 實際就是 SecurityManager 的 Factroy,對 SpringIniWebConfiguration 而言,它須要知道 SecurityManager 的 BeanName,該值由 SpringJSecurityFilter 的初始化參數「securityManagerBeanName」值決定。即 SpringJSecurityFilter,實際有兩個初始化參數:


    • config,是 ini 配置文件內容

    • securityManagerBeanName,是 SecurityManager 的 BeanName

SecurityUtils

這是 Shiro 中最重要的工具類,由它能夠方便地得到 Subject 和 SecurityManager。

雜項

  • AOP,提供 AOP 方面的支持,實現對某個類某個方法的攔截,從而使權限控制延伸至類的方法。

  • Cache,提供緩存支持

  • Codec,提供編碼方面的支持

  • Crypto,提供加密支持

  • IO,從多個資源位置讀寫原始數據

  • JNDI,提供 jndi 支持

  • util,工具類支持

  • 標籤類,用於 Web 頁面

經常使用標籤:

  • principal, 輸出當前用戶的標識

  • hasRole,判斷當前用戶是否屬於給定的角色,參數:name

  • hasPermission, 判斷當前用戶是否具備指定的權限,參數:type,action 或者 permission

  • isLoggedIn, 判斷當前用戶是否已經登陸

  • hasAnyRole,判斷當前用戶是否屬於給定的某個角色,參數:in

下面是本身整理的圖

http://www.cnblogs.com/dairongle/archive/2012/02/14/2350668.html

相關文章
相關標籤/搜索