1. 程式人生 > >深入學習RBAC系列模型——RBAC0模型的開發與學習心得

深入學習RBAC系列模型——RBAC0模型的開發與學習心得

RBAC0模型簡介:

  RBAC0是RBAC系列模型中的基礎模型,隨後的RBAC系列模型都將按照RBAC0基礎模型進行改進,所以學習RBAC模型就必須要牢牢掌握RBAC0模型的思想以及使用方法。

RBAC0引入了角色的思想解決了使用者與許可權之間的分離問題。使用者其實質上並沒有真正的許可權,只有當用戶成為了某一個特定的角色的時候才會被賦予特定的許可權。可以這麼理解,一個普通人,在正常情況下是無法合法持有槍支的,但當這個普通人蔘加公務員考試,併成為一名刑警之後,他就可以合法持有槍支了。這裡普通人為使用者,持有槍支為許可權,二者並沒有直接的關係,而是通過警察這一角色來進行關聯,將持有槍支合法化。換句話說,這個普通人永遠不能持有槍支,而警察永遠擁有持有槍支的許可權。每一個使用者都有可能成為警察,從而擁有持有槍支的許可權。這就是RBAC0中主要解決的許可權分離問題。

我們通過為某一使用者賦予角色來讓使用者擁有特定的許可權。這裡使用者、角色、許可權三者都可以是多個的。

  轉載請註明來源與作者:)

需要註明的是該模型其實已經包括了RBAC1的思想,RBAC0的思想是單純只有超級管理員才可以做一系列核心操作,而該系統對角色進行了分級也就是引入了RBAC1模型的思想。所以如果嚴格來說,該模型是基於RBAC0之上的RBAC1模型,大家在學習的時候只需要拋開角色類和使用者類中的繼承判斷就可以得到單純的RBAC0模型。

資料庫模型:

資料庫表中需要有USER(使用者表)、ROLE(角色表)、PERMISSION(許可權表)、PERMISSION_ASSIGNMENT(簡稱PA)(許可權與角色關聯表)、USER_ASSIGNMENT(簡稱UA)(使用者與角色關聯表),一共五張基礎表構成RBAC0模型。

當我們為某一使用者指定角色時我們就需要用到UA表了,管理員為使用者賦予角色時將uid和rid同時提交到PA表。系統在進行使用者角色判斷是,則從UA表中抽取其特定uid下的rid。不同的使用者可以成為相同的角色,而不同的角色同樣也可以被賦予給同一個使用者。舉例,網站中有使用者:A、B、C,網站中有角色:普通使用者、管理員、超級管理員。A、B、C都被賦予了普通使用者的許可權,此時,A又被賦予了管理員許可權來處理網站的大小事務,則A現在同時擁有普通使用者和管理員兩個角色。而經過一段時間後,超級管理員發現A工作忙不過來了,於是將B也提升為管理員。此時,管理員角色同時被賦給了A和B二人。

在為使用者賦予角色的同時,我們也要為角色賦予許可權。每一個角色可以指定不同的許可權,且許可權賦予是從0到無窮大。也就是說可以為同一個角色賦予多個許可權。而同一個許可權也可以賦予給多個角色,所以PA也是多對多的關係。比如角色普通使用者與管理員,他們同時擁有訪問網站並瀏覽資訊的許可權,所以同樣的一個瀏覽許可權被賦予給了不同的角色。而管理員不僅能看資訊,還能夠對資訊進行編輯、刪除。所以管理員同時擁有瀏覽、編輯、刪除三種不同的許可權。

系統對使用者進行許可權判斷的主要流程是,一個使用者登陸到網站,網站利用UA對使用者進行角色判斷並將使用者擁有的角色結果儲存為SESSION,當用戶進行操作時,網站將SESSION中的角色與PA進行比對然後對使用者所擁有的角色進行許可權判斷。

 RBAC0資料庫模型圖

使用者進行許可權操作的流程:

1、    對訪問客戶端進行登陸判斷,判斷是否登陸成功,如果不成功則提示使用者沒有登陸。

2、    使用者成功登陸後,系統將匹配成功的使用者ID從USER表中取出,並與UA表對應的UID進行比對,羅列出符合條件的所有rid並將其作為一個SESSION儲存。

3、    當用戶進行特定許可權操作時,系統使用者提交的pid與資料庫中的與資料庫中的rid進行匹配,然後再判斷使用者SESSION中是否有匹配的值,如果有則賦予使用者相應的許可權,並提示操作成功,否則提示使用者沒有許可權。

使用者許可權操作流程圖基於RBAC0

 系統流程圖

授權者如何為使用者進行許可權賦予:

1、    授權者自身首先需要擁有賦予其他使用者許可權的能力,且能賦予使用者的許可權能且只能賦予與自身許可權相當的權利,無法賦予使用者高於授權者自身許可權的能力。例如對網站資料庫進行操作的許可權只有頂級授權者有,普通授權者沒有這樣的許可權,那麼同樣的,普通授權者也無法賦予使用者這樣的許可權。

2、    首先,授權者要對角色進行許可權賦予,系統判斷授權者是否擁有為使用者賦予許可權的權利。

3、    當授權者有為使用者賦予許可權的能力時,顯示一個表單,羅列出所有比授權者許可權小的角色,並羅列出授權者自身所有許可權,如果賦予使用者的許可權,不在使用者現在擁有的角色許可權列表中,則新增一個符合條件的新角色給使用者。

 授權者授予使用者許可權流程圖基於RBAC0

關於在RBAC0中“角色管理員”角色的控制問題

首先,如果系統中需要引入角色管理員這一角色協助頂級管理員一起管理角色的話,我們需要考慮並遵循至少以下幾個要點:

1、    角色管理員角色的父角色必須是頂級管理員,直接受頂級管理員控制

2、    使用角色管理員這一角色的使用者必須為可信賴的使用者

3、    角色管理員無法建立子角色(可選)

4、    角色管理員必須嚴格遵循角色繼承思想,角色管理員無法對頂級管理員進行操作

5、    角色管理員只能對UA/PA/ROLE三表的完全或者不完全的控制權,對USER/PERMISSION表沒有任何操作許可權

 rbac0中“角色管理員“思想,以及角色許可權繼承思想

關於角色繼承的問題:

隨著系統中使用者、角色、許可權不斷增加,我們也許會考慮讓角色所有者自有派生其子角色的許可權,這裡我們就需要注意到一下幾個問題:

1、    我們可以對角色繼承進行強行控制,不是每一個角色都有派生其子角色的許可權,解決方案,在角色中建立一個“角色繼承”或者其他什麼名字的角色都可以,為這個角色新增唯一一個許可權,角色繼承許可權,我們應該在PA以及PERMISSION表中新增者一許可權的存在,當需要的時候我們為某一角色新增這一特別的角色就可以實現對角色繼承的嚴格控制。當然“角色繼承”這一角色我們也不是非要建立,可以在每次新增角色的時候為該角色賦予繼承許可權也可以了。但是由於許可權較多,所以有時候我們往往在刪除某一角色這一許可權的時候會疏忽,造成安全問題,所以我個人認為新增一個特定的專用於繼承的許可權是有必要的。

2、    子角色必須要遵循幾個要點,1.無法對父角色的許可權,行為,包括狀態進行瀏覽或者干涉,2.無法或者超出父角色許可權的角色,3.有且只有一個父角色,且當被父角色建立並繼承後,無法刪除父子關係,除非刪除該子角色。

3、    誰添加了這個角色就是這個角色的父角色,反應到資料庫表中就是超級管理員的ID為1,PID為0,添加了“管理員”這樣一個角色,那個這個角色的ID為2,PID為1,所以在角色表中的PID為0的有且只有一個。PID為每一個角色在建立是就必須要有的屬性,並且有且只有一個。

4、    同一個使用者不可能既有父角色也有子角色,這樣的道理就像一個人不可能自己給自己當爹或者當兒子是一樣的。

RBAC思想關鍵點:

1、    PERMISSION表中的fname(function name,類方法名)才是最後真正實現對許可權控制的一個要素,但他不一定要有。

2、    RBAC中的許可權控制,其實可以被理解為是對系統中各個類以及類中方法,引數的一個控制思想,比如:

文章管理(class article{})

|-新增文章(public function addArticle () {})

|-刪除文章(public function delArticle () {})

|-是否顯示作者(public $author)

對整個類進行精確控制,可以讓我們的系統安全性提高到一個新的級別,也就是任何一個使用者必須要有特定的角色,才可以訪問到特定的許可權,而這個許可權可能必須要滿足在比如必須要滿足是在article類中的addArticle方法才可以,如果是換了其他的地方則沒有,這樣我們也可以對類中方法的命名進行一個簡化,比如:

Class article {

   Public function add () {}

   Public function del () {}

   Public function show () {}

}

Class user {

   Public function add () {}

   Public function del () {}

   Public function show () {}

}

兩個類中都有add/del/show的方法,但是他們的意義其實是不同的,所以我們通過對訪問類的控制達到對方法的控制,比如我們允許“編輯”這個角色去訪問article類中的三個方法,但是我們不允許他進行對使用者的任何操作,所以,我們就可以首先限制他訪問的類,然後再對其訪問的類方法進行一個準確控制,甚至,我們可以對他的類成員進行一個準確控制,比如我們有一個類成員,是public $modifyTime專門存放修改時間的引數,那麼這個引數“編輯”不能訪問到,我們就可以在許可權管理下面新增上modifyTime在這個文章類下面,然後不賦予給“編輯”就可以讓編輯沒有許可權去操作這個成員了。而這個成員在“編輯”進行文章修改的時候會使用time()自動建立,所以就有效的防止了許可權的濫用,也將許可權最小化升級到了成員訪問控制最小化。當然這個例子也許並不怎麼恰當,但是有這樣的思想至少是對的,也許在不一定的某一個時候就需要用到這樣的極小許可權控制。當然訪問許可權的控制不是一定要使用面向物件進行程式設計才可以實現,我們也可以使用面向過程,只要對檔案進行訪問控制就可以實現面向物件同樣的效果,但是考慮到當一個系統了RBAC模型的時候,大概已經不是一個小系統了,所以運用面向物件的程式設計方法更加恰當。

3、    同一個擁有兩個或兩個以上角色時,如果這兩個角色的許可權重複是允許的,這並不能造成對某一個角色的許可權限制。比如當“文章編輯”角色擁有檢視新增刪除修改文章的許可權的時候,“使用者角色”擁有檢視文章的許可權,且test1使用者同時擁有者兩個角色,那麼他在UA表中應該是 UA{test1:文章編輯;test1:使用者}在PA表中的呈現時PA{文章編輯:show;文章編輯:add;文章編輯:edit;文章編輯:del;使用者:show}。而並不能減掉{文章編輯:show;}或者{使用者:show}中的其中任何一個,因為這涉及到今後角色的增刪。當test使用者的使用者許可權沒有的時候,也應該保證他能夠正常檢視文章。而如果當我們在為其賦予許可權的時候看到使用者角色已經有了檢視文章的許可權,而不將文章編輯中的show許可權賦予給使用者的時,那麼將來就會產生一個嚴重的問題,當test1的“使用者”角色被刪除,隨之而來的是即使test1是文章編輯的角色也會狗血的發現自己能對文章進行任何操作,但就是無法正常得檢視文章。

4、    角色間許可權不允許交叉繼承,只能垂直繼承,所有平級角色必須保持許可權平行。

5、    超級管理員具有唯一性,ID必須鎖死,且每一個系統中必須存在超級管理員。