rbac(role-based access control,基於角色的訪問控制),就是使用者通過角色與許可權進行關聯。簡單地說,乙個使用者擁有若干角色,每乙個角色擁有若干許可權。這樣,就構造成「使用者-角色-許可權」的授權模型。在這種模型中,使用者與角色之間,角色與許可權之間,一般者是多對多的關係。(如下圖)
角色是什麼?可以理解為一定數量的許可權的集合,許可權的載體。例如:乙個論壇系統,「超級管理員」、「版主」都是角色。版主可管理版內的帖子、可管理版內的使用者等,這些是許可權。要給某個使用者授予這些許可權,不需要直接將許可權授予使用者,可將「版主」這個角色賦予該使用者。
當使用者的數量非常大時,要給系統每個使用者逐一授權(授角色),是件非常煩瑣的事情。這時,就需要給使用者分組,每個使用者組內有多個使用者。除了可給使用者授權外,還可以給使用者組授權。這樣一來,使用者擁有的所有許可權,就是使用者個人擁有的許可權與該使用者所在使用者組擁有的許可權之和。(下圖為使用者組、使用者與角色三者的關聯關係)
在應用系統中,許可權表現成什麼?對功能模組的操作,對上傳檔案的刪改,選單的訪問,甚至頁面上某個按鈕、某個的可見性控制,都可屬於許可權的範疇。有些許可權設計,會把功能操作作為一類,而把檔案、選單、頁面元素等作為另一類,這樣構成「使用者-角色-許可權-資源」的授權模型。而在做資料表建模時,可把功能操作和資源統一管理,也就是都直接與許可權表進行關聯,這樣可能更具便捷性和易擴充套件性。(見下圖)
請留意許可權表中有一列「許可權型別」,我們根據它的取值來區分是哪一類許可權,如「menu」表示選單的訪問許可權、「operation」表示功能模組的操作許可權、「file」表示檔案的修改許可權、「element」表示頁面元素的可見性控制等。
這樣設計的好處有二。其一,不需要區分哪些是許可權操作,哪些是資源,(實際上,有時候也不好區分,如選單,把它理解為資源呢還是功能模組許可權呢?)。其二,方便擴充套件,當系統要對新的東西進行許可權控制時,我只需要建立乙個新的關聯表「許可權xx關聯表」,並確定這類許可權的許可權型別字串。
這裡要注意的是,許可權表與許可權選單關聯表、許可權選單關聯表與選單表都是一對一的關係。(檔案、頁面許可權點、功能操作等同理)。也就是每新增乙個選單,就得同時往這三個表中各插入一條記錄。這樣,可以不需要許可權選單關聯表,讓許可權表與選單表直接關聯,此時,須在許可權表中新增一列用來儲存選單的id,許可權表通過「許可權型別」和這個id來區分是種型別下的哪條記錄。
到這裡,rbac許可權模型的擴充套件模型的完整設計圖如下:
不是吧,猛一看以為是我自己的資料模型呢?我以為只有我的許可權系統有「頁面元素」這個概念呢。
--------------------------------------------
有時候需要單獨為乙個使用者增加一兩個許可權的,這時候單獨為這個使用者設計乙個「角色」,不值得,所以我設計的是:既可以通過角色為使用者分配許可權,也可以直接將許可權分配給使用者。
--------------------------------------------
我接觸過的幾個開發人員,都不明白為什麼要直接給使用者分配許可權,但是在軟體的實際應用中,如果完全基於「角色」為人員分配許可權,你會 發現角色之間重複、冗餘的許可權很多,這樣反覆的定義多種多樣的「角色」,還不如設計成可以直接為人員分配許可權呢。
--------------------------------------------
許可權管理基本上分為以下幾個步驟:
1、定義許可權-》定義角色-》為人員分配角色(或者直接分配許可權),這是乙個分配許可權的過程;
--------------------------------------------
2、定義受保護資源-》為「受保護資源」指定授權許可權,這是乙個授權的過程;
--------------------------------------------
3、應用程式請求「受保護資源」-》「受保護資源」的授權許可權與人員持有的許可權進行匹配-》匹配成功,允許訪問資源,匹配失敗,不允許訪問資源,這是乙個認證的過程。
--------------------------------------------
上面這三個過程,是典型的「操作許可權」的流程。
--------------------------------------------
關於「頁面元素」的控制,目前多數許可權管理系統,都是用「自定義許可權標籤」來控制頁面元素的顯示與否的。
我目前也是這樣實現的,但是我一直認為:其實用「自定義許可權標籤」來控制頁面元素的顯示與否,跟直接在檢視中使用程式邏輯判斷,是一樣的,並沒有做到「靈活配置」,當許可權編碼改變,或者許可權含義改變時,還是要去動頁面的標籤,所以跟寫死沒什麼分別。
如果頁面元素是通過服務端組裝成json,或者別的格式的資料,然後返回到檢視層進行渲染,這樣的話,就可以做到「頁面元素的許可權靈活配置了」,可以通過資料庫定義那些按鈕對那些許可權或角色進行顯示。
「服務端組裝檢視層元件,返回檢視層渲染」,這個模式雖然做到了「對頁面元素的許可權靈活配置」,但是犧牲掉了很多東西,比如加大了服務端的複雜度,使得頁面的設計更加「程式設計師化」,而不是「美工化」等。
--------------------------------------------
至於最關鍵的「資料許可權」,也就是人員對資料的讀取深度的控制,是更為複雜的流程。
--------------------------------------------
對於「資料深度」的控制,我目前的做法是和業務結合的非常緊密,即:在讀取資料的程式中,比如「列表」頁,首先判斷當前登陸者有沒有「讀取任意深度的許可權」,如果有,就不做讀取限制;如果沒有,則判斷當前登入人員是不是部門主管,如果是,則遞迴讀取本部門下的所有資料,如果不是主管,則只讀取自己的資料。
--------------------------------------------
「資料深度」的控制,細設計的話,應該可以更通用,更靈活,大家有什麼更好的思路,可以討論一下。
--------------------------------------------
我目前設計的是乙個人員只能有乙個「角色」,當然,如果設計成乙個人員有多個「角色」,也不是很複雜的事情,在「使用者表」和「角色表」之間增加乙個「使用者-角色對映表」就可以了,但是為了系統的簡單起見,我把這種設計簡化了。
--------------------------------------------
以下是我的「許可權控制」的部分資料模型:
許可權的設計
rbac role based access control,基於角色的訪問控制 就是使用者通過角色與許可權進行關聯。簡單地說,乙個使用者擁有若干角色,每乙個角色擁有若干許可權。這樣,就構造成 使用者 角色 許可權 的授權模型。在這種模型中,使用者與角色之間,角色與許可權之間,一般者是多對多的關係。...
許可權選單的設計
1.資源表 1.1 resource resourceid,resourcenamespace,description 1.2 category categoryid,name,parentid,description 1.3 module moduleid,name,url,description...
許可權表的設計
設計表 users 使用者列表 場 userid,username,userpermission roles 角色表 場 roleid,rolename,rolepermission userinrole 對應表使用者角色 場 userid,roleid permissionlist 許可權列表 字...