漫談權限系統之技術策略以及基于RBAC的實現
根據上面的需求描述以及對需求的分析,我們得知通常的一個中小型系統對于權限系統所需實現的功能以及非功能性的需求,在下面我們將根據需求從技術角度上分析實現的策略以及基于目前兩種比較流行的權限設計思想來討論關于權限系統的實現。
1.1. 技術策略
· 身份認證
在 B/S 的系統中,為識別用戶身份,通常使用的技術策略為將用戶的身份記錄在 Session
中,也就是當用戶登錄時即獲取用戶的身份信息,并將其記錄到 Session 里,當需要進行身份認證的時候通過從 Session
中獲取用戶的身份信息來實現用戶的身份認證。
· 資源權限校驗
資源權限校驗取決于系統的授權模型,這塊將在之后進行詳細的闡述。
· 數據權限校驗
數據權限校驗取決于系統的授權模型,這塊將在之后進行詳細的闡述。
· 授權模型
授權模型作為權限系統的核心,從本質上決定了權限系統的易用性,這個易用性包括權限的授予和權限的校驗,并同時也決定了權限的繼承,權限的排斥和包含等方面的實現。
在經歷了這么多年的發展,授權模型在目前中小型應用系統接受的比較多的主要有 RBAC 模型和 ACL 模型,將在之后展開專門的篇幅進行講解。
· 權限校驗的體現
權限校驗的體現在中小型系統中體現出來的通常只是對于系統菜單、按鈕顯示的控制和對于擁有權限的數據的訪問上。
它們共同依賴于資源權限校驗和數據權限校驗,對于系統菜單、按鈕的顯示上的控制在 B/S 中通常采用的技術策略為在生成菜單、按鈕的 Html
時做權限級的判斷,當操作主體不具備權限時則不生成該菜單、按鈕的 Html
,從技術角度分析為方便使用者,避免使用者調用權限校驗接口,通常的做法為提供菜單、按鈕的標簽,通過此標簽生成的菜單和按鈕即為經過權限過濾的。
· 高性能
為提高權限系統在授權以及校驗權限時的性能,通常的做法為采用緩存技術以及加強權限系統的管理建設,加強權限系統的管理建設有助于建立一個最為適合需求的權限結構,同時做到了簡化系統權限授予。
· 安全性
安全性方面來講在 B/S 系統中通常有兩個方面需要控制:
通過非法途徑訪問系統文件
在 Java 的 Web 應用中通常采用的技術策略為將需要受保護的文件放入 WEB-INF 文件夾中,大家都知道在 WEB-INF 下的文件除了在服務器上能直接訪問外,通過普通的 URL 是無法訪問到的。
其次的做法為做 Filter ,即對需要受保護的資源做訪問的 Filter ,如操作者不具備權限則直接報出錯誤。
通過非法途徑訪問系統操作
通常采用的技術策略為對每個直接暴露對外的需要受權限保護的對象做操作級別的權限控制,簡單來說在 Web 系統中通常采用 MVC 框架來實現,通常
Command 層是直接對外的,為防止用戶通過 URL 或其他方式訪問 Command
,從技術上我們需要考慮對現有系統的盡量少的侵入性,所以通常采用的做法是在 Command 之上做 Before Interceptor 或
Proxy ,在此 Interceptor 或 Proxy 中做權限的校驗,以確認操作者具有相應的權限。
經過上面的描述,我們已經基本了解到滿足權限系統需求的技術實現策略,從中我們也可以看出權限系統中最為重要的為授權模型,由于權限系統的通用性,在業界也是推出了不少的授權模型,在這里我們已目前比較通用的兩種授權模型來具體講解權限系統的完整實現。
1.2. 基于 RBAC 的實現
1.2.1. RBAC 介紹
RBAC 模型作為目前最為廣泛接受的權限模型,在此也將對其模型進行簡要的介紹, RBAC 模型成功的經典應用案例當屬 Unix 系統了。
NIST
( The National Institute of Standards and Technology ,美國國家標準與技術研究院)標準
RBAC 模型由 4 個部件模型組成,這 4 個部件模型分別是基本模型 RBAC0 ( Core RBAC )、角色分級模型 RBAC1 (
Hierarchal RBAC )、角色限制模型 RBAC2 ( Constraint RBAC )和統一模型 RBAC3 (
Combines RBAC ) [1] 。 RBAC0 模型如圖 1 所示。

圖表 1 RBAC 0 模型
· RBAC0 定義了能構成一個 RBAC 控制系統的最小的元素集合
在 RBAC 之中 , 包含用戶 users(USERS) 、角色 roles(ROLES) 、目標 objects(OBS) 、操作
operations(OPS) 、許可權 permissions(PRMS) 五個基本數據元素,權限被賦予角色 ,
而不是用戶,當一個角色被指定給一個用戶時,此用戶就擁有了該角色所包含的權限。會話 sessions 是用戶與激活的角色集合之間的映射。
RBAC0 與傳統訪問控制的差別在于增加一層間接性帶來了靈活性, RBAC1 、 RBAC2 、 RBAC3 都是先后在 RBAC0 上的擴展。
· RBAC1 引入角色間的繼承關系
角色間的繼承關系可分為一般繼承關系和受限繼承關系。一般繼承關系僅要求角色繼承關系是一個絕對偏序關系,允許角色間的多繼承。而受限繼承關系則進一步要求角色繼承關系是一個樹結構。
· RBAC2 模型中添加了責任分離關系
RBAC2 的約束規定了權限被賦予角色時 , 或角色被賦予用戶時 , 以及當用戶在某一時刻激活一個角色時所應遵循的強制性規則。責任分離包括靜態責任分離和動態責任分離。約束與用戶 - 角色 - 權限關系一起決定了 RBAC2 模型中用戶的訪問許可。
· RBAC3 包含了 RBAC1 和 RBAC2
既提供了角色間的繼承關系,又提供了責任分離關系。
1.2.2. 實現方案
通過上面章節對 RBAC 的介紹,從 RBAC 模型中我們可以看出它已經實現了一個使用起來很方便的授權模型,并同時也就權限的繼承,權限的排斥和包含提出了解決的模型。
那么現在的關鍵是我們需要來看看基于 RBAC 到底是怎么實現權限系統的需求的呢?在這里我們針對在技術策略中未描述的授權模型和權限校驗部分做實現方案的講解。
· 授權模型
授權模型遵循 RBAC 進行搭建,即建立如上圖表一的模型。
針對授權模型中的幾個關鍵部分我們進行描述:
授權
按照 RBAC 的模型,在授權時分為配置資源以及資源的操作、授予角色對資源的操作權限、分配角色給用戶這幾個步驟來完成。
從這幾個步驟我們進行分析:
配置資源以及資源的操作
實現這步非常的簡單,直接維護資源以及資源操作兩個對象的持久即可實現。
授予角色對資源的操作權限
實現這步同樣非常的簡單,維護角色與資源的關聯模型即可。
分配角色給用戶
實現這步同樣非常的簡單,維護角色與用戶的關聯模型即可。
權限的繼承
權限的繼承在 RBAC 的模型中通過增加角色的自關聯來實現,即角色可擁有子角色,子角色繼承父角色的權限。
按照此模型可以看出在授權時維護權限的繼承也是非常的簡單,維護角色的自關聯模型即可。
權限的排斥和包含
權限的排斥和包含這塊我沒有具體看 RBAC 的規范,通常的做法是通過在資源的操作權限模型中增加自關聯模型以定義哪些資源的操作權限是排斥和包含的,在授權時可以看到同樣需要維護的只是資源權限的自關聯模型。
· 資源權限校驗
根據上面的授權模型,在做資源權限校驗的時候需要經過以下步驟:
判斷用戶所在的角色是否擁有對資源進行操作的權限
獲取用戶所擁有的角色,遍歷其角色,以各角色建立 Session ,并通過類似的 role.doPrivilege(Resource,Operation) 的方式來判斷該角色是否具備權限,如具備則直接返回,如不具備則直到遍歷結束。
遞規用戶所在角色的父角色判斷是否擁有對資源進行操作的權限
當遍歷完用戶本身的角色得到用戶不具備對資源進行該操作的權限時,則開始遞規其所在角色的父角色來判斷是否擁有對資源進行操作的權限,過程同上,如確定某角色具備,則返回,如不具備直到遞規結束。
· 數據權限校驗
在 RBAC 模型中沒有明確定義數據權限的實現策略,鑒于此首先要講解下基于 RBAC 模型的數據授權模型的建立,基于 RBAC
模型,將數據映射為 RBAC
中的資源,對數據的操作則映射為資源的操作,同樣的是將此資源以及資源的操作構成的權限授予給角色,將用戶分配給角色完成數據權限的授權過程。
但根據數據權限校驗的需求,數據的權限也是需要繼承的,而且數據權限的授予對象需要是多種,這樣的話就對上面根據 RBAC 映射形成的數據權限的授權模型造成了沖擊,需要重構上面的授權模型來滿足需求。
為實現數據權限的繼承,需要將 RBAC
模型中的資源重構為允許自關聯的模型,為實現數據權限能夠授予給多種對象,需要將本來資源操作權限授予給角色的模型演變為數據操作權限授予給角色、組織機
構或具體人員,根據 RBAC 模型,同樣的建立一個中間對象,此對象和數據操作權限所授予的對象做 1
對多的關聯,在經過這樣的重構之后數據權限的授權模型就形成了,也滿足了數據權限的繼承和授予給多種對象的需求。

圖表 2 基于 RBAC 演變的數據權限模型
上面的圖中少畫了數據的自關聯。根據上面的數據權限模型,來看看數據權限的校驗是怎么樣去實現呢?
在做數據權限校驗的時候我們需要實現的為兩種方式,一種是獲取操作主體具有數據操作權限的全部數據,另外一種為分頁獲取操作主體具有數據操作權限的數據。
就這兩種方式分別來進行闡述:
獲取操作主體具有數據操作權限的全部數據
從數據庫中獲取所有數據,遍歷取出的數據從數據權限模型中獲取相應的擁有數據操作權限的權限擁有者,如果該數據未配置數據操作權限的控制,那么就無需對該
數據進行權限級的判斷,如配置了,則需判斷當前用戶是否在該數據操作權限所對應的擁有者中,如用戶不在,則需遞規獲取該數據的父數據的操作權限的擁有者,
到用戶擁有權限或遞規結束時終止。
分頁獲取操作主體具有數據操作權限的數據
分頁的做法和上面差不多,只是在獲取了所有的數據后在內存中做分頁返回。
1.2.3. 優缺點分析
從上面的基于 RBAC 的實現方案中可以看出基于 RBAC 模型的優點在于:
· 易用和高效的授權方式
用戶在進行授權時只需對角色進行授權,之后將相應的角色分配給用戶即可。
· 簡便和高效的授權模型維護
在技術角度來講,進行授權模型的維護上因為基本只需要維護關聯模型而顯得簡單而高效。
缺點在于:
· 復雜的權限校驗
在進行權限校驗時需要不斷的遍歷和遞規,造成了性能的影響。
· 對于數據權限的不夠支持
沒有明確的數據權限模型,可以看到在經過重構的數據權限模型其實已經和 RBAC 模型有一定的出入,而且在數據權限的校驗上實現起來是非常的低效。