Apache Shiro是一個(gè)功能強(qiáng)大,靈活的開(kāi)源的安全框架,它可以干脆利落的處理身份驗(yàn)證、授權(quán)、企業(yè)會(huì)話管理和加密。
與spring security一樣,都是一個(gè)作為權(quán)限管理的安全框架。但是與spring security相比,在于shiro使用了比較簡(jiǎn)單、易懂且易于使用的授權(quán)方式。
shiro官網(wǎng):http://shiro.apache.org/
Apache Shiro特征
Apache Shiro是一個(gè)全面的、功能豐富的安全框架,如圖描述了shiro的一些集中關(guān)注點(diǎn)。

其中綠色的四大塊分別是認(rèn)證(Authentication)、授權(quán)(Authorization)、會(huì)話管理(Session Management)、加密(Cryptography),它們被shiro的開(kāi)發(fā)團(tuán)隊(duì)稱之為應(yīng)用程序安全的四大基石:
- 認(rèn)證:用戶的識(shí)別,通常被稱為用戶登錄
- 授權(quán):做訪問(wèn)控制,比如某個(gè)用戶是否具有某個(gè)操作的使用權(quán)限
- 會(huì)話管理:特定于用戶的會(huì)話管理
- 加密:對(duì)數(shù)據(jù)源使用加密算法加密保證數(shù)據(jù)安全,同時(shí)保證它容易使用
當(dāng)然了,還有其他功能來(lái)支持和加強(qiáng)這些不同應(yīng)用環(huán)境下安全領(lǐng)域的關(guān)注點(diǎn),特別是對(duì)以下功能的支持:
- 首先是web的支持,shiro提供了web支持API,可以輕松的保護(hù)web應(yīng)用程序的安全,
- 接下來(lái)是緩存,緩存是shiro保證安全操作快速高效的重要手段
- 并發(fā):shiro支持多線程應(yīng)用程序的并發(fā)特性
- 測(cè)試:支持單元測(cè)試和集成測(cè)試,確保代碼和預(yù)想的一樣安全
- 支持run as功能,這個(gè)功能允許用戶假設(shè)另一個(gè)用戶的身份,當(dāng)然了,這是在許可的前提下才可以
- remember me功能,它可以跨session記錄用戶的身份,只有在強(qiáng)制需要時(shí),才需要登錄
這里需要注意,shiro不會(huì)去維護(hù)用戶和權(quán)限,需要我們自己去設(shè)計(jì)和實(shí)現(xiàn),然后提供相應(yīng)的接口注入給shiro
高級(jí)別的概述
在概念層,shiro架構(gòu)主要包含3個(gè)主要理念:subject、securitymanager、realm,下圖為這些組件如何交互的高級(jí)概述圖,我們分別介紹每個(gè)概念。

subject
主體,代表了當(dāng)前用戶,subject可以是一個(gè)人,也可以是第三方服務(wù),守護(hù)進(jìn)程的賬戶或者其他當(dāng)前和軟件交互的任何事件比如網(wǎng)絡(luò)爬蟲(chóng)、機(jī)器人等,它是一個(gè)抽象的概念。
所有的subject都綁定到securitymanager,與subject所有的交互都會(huì)委托給securitymanager,可以把subject認(rèn)為是一個(gè)門面,securitymanager才是一個(gè)實(shí)際的執(zhí)行者。
SecurityManager
securitymanager是一個(gè)安全的管理器,即所有與安全有關(guān)的操作都會(huì)與securitymanager交互,它管理著所有的subject,可以看出它是shiro的核心,它負(fù)責(zé)與后面介紹的其他組件進(jìn)行交互。
Realm
shiro從realm中獲取安全數(shù)據(jù),包括用戶角色、權(quán)限等等,securitymanager要驗(yàn)證身份的話,需要從realm獲取相應(yīng)的用戶,然后進(jìn)行比較,以確定用戶身份是否合法,也需要從realm中得到用戶相應(yīng)的角色以及權(quán)限進(jìn)行驗(yàn)證用戶是否能進(jìn)行操作,可以把realm看成datasource,即安全的數(shù)據(jù)源
最簡(jiǎn)單的一個(gè)shiro應(yīng)用,首先是應(yīng)用代碼通過(guò)subject來(lái)進(jìn)行授權(quán)和認(rèn)證,而subject又委托給securitymanager,我們需要給securitymanager注入realm,從而讓securitymanager能夠得到合法的用戶及其權(quán)限進(jìn)行判斷。
Apache Shiro架構(gòu)
接下來(lái)看一下Apache Shiro的架構(gòu)圖

Authenticator
這是用戶認(rèn)證管理器,這個(gè)組件主要是用于處理用戶的登錄邏輯,它通過(guò)調(diào)用realm的接口來(lái)判斷登錄用戶的身份,這里涉及到用戶認(rèn)證策略,比如如果系統(tǒng)中配置了多個(gè)realm,則需要使用Authentication Strategy來(lái)協(xié)調(diào)這些realm以便決定一個(gè)用戶的登錄和認(rèn)證是成功還是失敗。
比如一個(gè)realm驗(yàn)證成功了,但是其他都失敗了,這次認(rèn)證是算成功還是失敗呢,還是說(shuō)必須所有的realm都成功了才算成功,或者第一個(gè)realm成功就算成功,因此我們需要一個(gè)策略,這個(gè)策略相對(duì)還是挺復(fù)雜的。
Authorizer
這是權(quán)限管理器,這個(gè)組件主要是用來(lái)做用戶的訪問(wèn)控制,通俗來(lái)說(shuō),就是決定用戶能做什么,不能做什么,和Authenticator類似,Authorizer它也知道怎么協(xié)調(diào)多個(gè)realm數(shù)據(jù)源的數(shù)據(jù),它有自己的一套策略
Session Manager
會(huì)話管理器,它知道如何創(chuàng)建會(huì)話,管理用戶會(huì)話的生命周期,以便在所有運(yùn)行環(huán)境下都能給用戶提供一個(gè)健壯的會(huì)話管理體驗(yàn),shiro在任何環(huán)境下都可以在本地管理用戶會(huì)話,即便沒(méi)有web容器也可以,這在安全管理框架中算是獨(dú)門絕技了。
當(dāng)然如果當(dāng)前環(huán)境中有會(huì)話管理機(jī)制,比如servlet容器,則shiro默認(rèn)會(huì)使用該環(huán)境的會(huì)話管理機(jī)制,而如果像控制臺(tái)這種獨(dú)立的應(yīng)用程序,本身沒(méi)有會(huì)話管理機(jī)制的時(shí)候,shiro就會(huì)使用內(nèi)部的會(huì)話管理器來(lái)給應(yīng)用開(kāi)發(fā)提供一致的編程體驗(yàn)。
Session Dao
它允許用戶使用任何類型的數(shù)據(jù)源來(lái)存儲(chǔ)session數(shù)據(jù),它主要是用來(lái)代替Session Manager執(zhí)行session相關(guān)的增刪改查,這個(gè)接口允許我們將任意種類的數(shù)據(jù)、存儲(chǔ)方式引入到session管理的基礎(chǔ)框架之中。
Cache Manager
用于創(chuàng)建和維護(hù)一些在其他shiro組件中用到的cache實(shí)例,維護(hù)這些cache實(shí)例的生命周期,緩存用于存儲(chǔ)那些從后端獲取到的用戶驗(yàn)證、及權(quán)限控制方面的數(shù)據(jù)來(lái)提高性能。在獲取數(shù)據(jù)時(shí),先是從緩存查找,如果沒(méi)有,再調(diào)用后端接口從其他數(shù)據(jù)源獲取,shiro允許用戶使用其他更加現(xiàn)代的企業(yè)級(jí)數(shù)據(jù)源來(lái)代替內(nèi)部的默認(rèn)實(shí)現(xiàn),以提高更高的性能和更好的用戶體驗(yàn)。
Cryptography
加密技術(shù),對(duì)于一個(gè)企業(yè)級(jí)的安全框架來(lái)說(shuō),加密算是其固有的一種特性,shiro的Crypto包裝包含了一系列的易于理解和使用的加密hash輔助類,所有的類都是經(jīng)過(guò)精心設(shè)計(jì),相比于java本身提供的一套反人類的加密組件,shiro的這套加密組件簡(jiǎn)直好用太多了。
Realm
是連接shiro和安全數(shù)據(jù)的橋梁,任何時(shí)候當(dāng)shiro需要執(zhí)行登錄或者訪問(wèn)控制的時(shí)候,都需要調(diào)用已經(jīng)配置的realm接口去獲取數(shù)據(jù),一個(gè)應(yīng)用程序可以配置一個(gè)或者多個(gè)realm,通常來(lái)說(shuō)一個(gè)數(shù)據(jù)源會(huì)配置一個(gè)。