擴展RBAC用戶角色權限設計方案

擴展RBAC用戶角色權限設計方案

RBAC(Role-Based Access Control,基於角色的訪問控制),就是用戶通過角色與權限進行關聯。簡單地說,一個用戶擁有若干角色,每一個角色擁有若干權限。這樣,就構造成“用戶-角色-權限”的授權模型。在這種模型中,用戶與角色之間,角色與權限之間,一般者是多對多的關係。(如下圖)



角色是什麼?可以理解爲一定數量的權限的集合,權限的載體。例如:一個論壇系統,“超級管理員”、“版主”都是角色。版主可管理版內的帖子、可管理版內的用戶等,這些是權限。要給某個用戶授予這些權限,不需要直接將權限授予用戶,可將“版主”這個角色賦予該用戶。 

 

當用戶的數量非常大時,要給系統每個用戶逐一授權(授角色),是件非常煩瑣的事情。這時,就需要給用戶分組,每個用戶組內有多個用戶。除了可給用戶授權外,還可以給用戶組授權。這樣一來,用戶擁有的所有權限,就是用戶個人擁有的權限與該用戶所在用戶組擁有的權限之和。(下圖爲用戶組、用戶與角色三者的關聯關係)

在應用系統中,權限表現成什麼?對功能模塊的操作,對上傳文件的刪改,菜單的訪問,甚至頁面上某個按鈕、某個圖片的可見性控制,都可屬於權限的範疇。有些權限設計,會把功能操作作爲一類,而把文件、菜單、頁面元素等作爲另一類,這樣構成“用戶-角色-權限-資源”的授權模型。而在做數據表建模時,可把功能操作和資源統一管理,也就是都直接與權限表進行關聯,這樣可能更具便捷性和易擴展性。(見下圖)



請留意權限表中有一列“權限類型”,我們根據它的取值來區分是哪一類權限,如“MENU”表示菜單的訪問權限、“OPERATION”表示功能模塊的操作權限、“FILE”表示文件的修改權限、“ELEMENT”表示頁面元素的可見性控制等。

 

這樣設計的好處有二。其一,不需要區分哪些是權限操作,哪些是資源,(實際上,有時候也不好區分,如菜單,把它理解爲資源呢還是功能模塊權限呢?)。其二,方便擴展,當系統要對新的東西進行權限控制時,我只需要建立一個新的關聯表“權限XX關聯表”,並確定這類權限的權限類型字符串。

 

這裏要注意的是,權限表與權限菜單關聯表、權限菜單關聯表與菜單表都是一對一的關係。(文件、頁面權限點、功能操作等同理)。也就是每添加一個菜單,就得同時往這三個表中各插入一條記錄。這樣,可以不需要權限菜單關聯表,讓權限表與菜單表直接關聯,此時,須在權限表中新增一列用來保存菜單的ID,權限表通過“權限類型”和這個ID來區分是種類型下的哪條記錄。

 

到這裏,RBAC權限模型的擴展模型的完整設計圖如下:



隨着系統的日益龐大,爲了方便管理,可引入角色組對角色進行分類管理,跟用戶組不同,角色組不參與授權。例如:某電網系統的權限管理模塊中,角色就是掛在區局下,而區局在這裏可當作角色組,它不參於權限分配。另外,爲方便上面各主表自身的管理與查找,可採用樹型結構,如菜單樹、功能樹等,當然這些可不需要參於權限分配。

有時候需要單獨爲一個用戶增加一兩個權限的,這時候單獨爲這個用戶設計一個“角色”,不值得,所以我設計的是:既可以通過角色爲用戶分配權限,也可以直接將權限分配給用戶。

--------------------------------------------

我接觸過的幾個開發人員,都不明白爲什麼要直接給用戶分配權限,但是在軟件的實際應用中,如果完全基於“角色”爲人員分配權限,你會 發現角色之間重複、冗餘的權限很多,這樣反覆的定義多種多樣的“角色”,還不如設計成可以直接爲人員分配權限呢。

--------------------------------------------

權限管理基本上分爲以下幾個步驟:

1、定義權限-》定義角色-》爲人員分配角色(或者直接分配權限),這是一個分配權限的過程;

--------------------------------------------

2、定義受保護資源-》爲“受保護資源”指定授權權限,這是一個授權的過程;

--------------------------------------------

3、應用程序請求“受保護資源”-》“受保護資源”的授權權限與人員持有的權限進行匹配-》匹配成功,允許訪問資源,匹配失敗,不允許訪問資源,這是一個認證的過程。

--------------------------------------------

上面這三個過程,是典型的“操作權限”的流程。

--------------------------------------------

關於“頁面元素”的控制,目前多數權限管理系統,都是用“自定義權限標籤”來控制頁面元素的顯示與否的。

我目前也是這樣實現的,但是我一直認爲:其實用“自定義權限標籤”來控制頁面元素的顯示與否,跟直接在視圖中使用程序邏輯判斷,是一樣的,並沒有做到“靈活配置”,當權限編碼改變,或者權限含義改變時,還是要去動頁面的標籤,所以跟寫死沒什麼分別。

 

如果頁面元素是通過服務端組裝成json,或者別的格式的數據,然後返回到視圖層進行渲染,這樣的話,就可以做到“頁面元素的權限靈活配置了”,可以通過數據庫定義那些按鈕對那些權限或角色進行顯示。

 

“服務端組裝視圖層組件,返回視圖層渲染”,這個模式雖然做到了“對頁面元素的權限靈活配置”,但是犧牲掉了很多東西,比如加大了服務端的複雜度,使得頁面的設計更加“程序員化”,而不是“美工化”等。

--------------------------------------------

 

至於最關鍵的“數據權限”,也就是人員對數據的讀取深度的控制,是更爲複雜的流程。

 

 

--------------------------------------------

對於“數據深度”的控制,我目前的做法是和業務結合的非常緊密,即:在讀取數據的程序中,比如“列表”頁,首先判斷當前登陸者有沒有“讀取任意深度的權限”,如果有,就不做讀取限制;如果沒有,則判斷當前登錄人員是不是部門主管,如果是,則遞歸讀取本部門下的所有數據,如果不是主管,則只讀取自己的數據。

--------------------------------------------

“數據深度”的控制,細設計的話,應該可以更通用,更靈活,大家有什麼更好的思路,可以討論一下。

--------------------------------------------

我目前設計的是一個人員只能有一個“角色”,當然,如果設計成一個人員有多個“角色”,也不是很複雜的事情,在“用戶表”和“角色表”之間增加一個“用戶-角色映射表”就可以了,但是爲了系統的簡單起見,我把這種設計簡化了。

--------------------------------------------

以下是我的“權限控制”的部分數據模型:

 

我目前比較關心的是:

1、數據權限(讀取數據的深度)有什麼更通用的設計?

2、頁面元素的控制,除了使用“自定義權限標籤”,或者“服務端組裝視圖層組件”兩種方法,還有沒有更好的設計?


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