?前言: ?
? 權(quán)限往往是一個(gè)極其復(fù)雜的問題,但也可簡(jiǎn)單表述為這樣的邏輯表達(dá)式:判斷“Who對(duì)What(Which)進(jìn)行How的操作”的邏輯表達(dá)式是否為真。針對(duì)不同的
應(yīng)用
,需要根據(jù)項(xiàng)目的實(shí)際情況和具體架構(gòu),在維護(hù)性、靈活性、完整性等N多個(gè)方案之間比較權(quán)衡,選擇符合的方案。 ?
? 目標(biāo): ?
? 直觀,因?yàn)橄到y(tǒng)最終會(huì)由最終用戶來維護(hù),權(quán)限分配的直觀和容易理解,顯得比較重要,系統(tǒng)不辭勞苦的實(shí)現(xiàn)了組的繼承,除了功能的必須,更主要的就是因?yàn)樗銐蛑庇^。 ?
? 簡(jiǎn)單,包括概念數(shù)量上的簡(jiǎn)單和意義上的簡(jiǎn)單還有功能上的簡(jiǎn)單。想用一個(gè)權(quán)限系統(tǒng)解決所有的權(quán)限問題是不現(xiàn)實(shí)的。設(shè)計(jì)中將常常變化的“定制”特點(diǎn)比較強(qiáng)的部分判斷為業(yè)務(wù)邏輯,而將常常相同的“通用”特點(diǎn)比較強(qiáng)的部分判斷為權(quán)限邏輯就是基于這樣的思路。 ?
? 擴(kuò)展,采用可繼承在擴(kuò)展上的困難。的Group概念在支持權(quán)限以組方式定義的同時(shí)有效避免了重定義時(shí) ?
? 現(xiàn)狀: ?
? 對(duì)于在企業(yè)環(huán)境中的訪問控制
方法
,一般有三種: ?
? 1.自主型訪問控制方法。目前在我國(guó)的大多數(shù)的信息系統(tǒng)中的訪問控制模塊中基本是借助于自主型訪問控制方法中的訪問控制列表(ACLs)。 ?
? 2.強(qiáng)制型訪問控制方法。用于多層次安全級(jí)別的
軍事
應(yīng)用。 ?
? 3.基于角色的訪問控制方法(RBAC)。是目前公認(rèn)的解決大型企業(yè)的統(tǒng)一資源訪問控制的有效方法。其顯著的兩大特征是:1.減小授權(quán)管理的復(fù)雜性,降低管理開銷。2.靈活地支持企業(yè)的安全策略,并對(duì)企業(yè)的變化有很大的伸縮性。 ?
? 名詞: ?
? 粗粒度:表示類別級(jí),即僅考慮對(duì)象的類別(the ? type ? of ? object),不考慮對(duì)象的某個(gè)特 ?
? 定實(shí)例。比如,用戶管理中,創(chuàng)建、刪除,對(duì)所有的用戶都一視同仁,并不區(qū)分操作的具體對(duì)象實(shí)例。 ?
? 細(xì)粒度:表示實(shí)例級(jí),即需要考慮具體對(duì)象的實(shí)例(the ? instance ? of ? object),當(dāng)然,細(xì) ?
? 粒度是在考慮粗粒度的對(duì)象類別之后才再考慮特定實(shí)例。比如,合同管理中,列表、刪除,需要區(qū)分該合同實(shí)例是否為當(dāng)前用戶所創(chuàng)建。 ?
? 原則: ?
? 權(quán)限邏輯配合業(yè)務(wù)邏輯。即權(quán)限系統(tǒng)以為業(yè)務(wù)邏輯提供服務(wù)為目標(biāo)。相當(dāng)多細(xì)粒度的權(quán)限問題因其極其獨(dú)特而不具通用意義,它們也能被理解為是“業(yè)務(wù)邏輯”的一部分。比如,要求:“合同資源只能被它的創(chuàng)建者刪除,與創(chuàng)建者同組的用戶可以修改,所有的用戶能夠?yàn)g覽”。這既可以認(rèn)為是一個(gè)細(xì)粒度的權(quán)限問題,也可以認(rèn)為是一個(gè)業(yè)務(wù)邏輯問題。在這里它是業(yè)務(wù)邏輯問題,在整個(gè)權(quán)限系統(tǒng)的架構(gòu)設(shè)計(jì)之中不予過多考慮。當(dāng)然,權(quán)限系統(tǒng)的架構(gòu)也必須要能支持這樣的控制判斷。或者說,系統(tǒng)提供足夠多但不是完全的控制
能力
。即,設(shè)計(jì)原則歸結(jié)為:“系統(tǒng)只提供粗粒度的權(quán)限,細(xì)粒度的權(quán)限被認(rèn)為是業(yè)務(wù)邏輯的職責(zé)”。 ?
? 需要再次強(qiáng)調(diào)的是,這里表述的權(quán)限系統(tǒng)僅是一個(gè)“不完全”的權(quán)限系統(tǒng),即,它不提供所有關(guān)于權(quán)限的問題的解決方法。它提供一個(gè)基礎(chǔ),并解決那些具有“共性”的(或者說粗粒度的)部分。在這個(gè)基礎(chǔ)之上,根據(jù)“業(yè)務(wù)邏輯”的獨(dú)特權(quán)限需求,編碼實(shí)現(xiàn)剩余部分(或者說細(xì)粒度的)部分,才算完整。回到權(quán)限的問題公式,通用的設(shè)計(jì)僅解決了Who+What+How ? 的問題,其他的權(quán)限問題留給業(yè)務(wù)邏輯解決。 ?
? 概念: ?
? Who:權(quán)限的擁用者或主體(Principal、User、Group、Role、Actor等等) ?
? What:權(quán)限針對(duì)的對(duì)象或資源(Resource、Class)。 ?
? How:具體的權(quán)限(Privilege, ? 正向授權(quán)與負(fù)向授權(quán))。 ?
? Role:是角色,擁有一定數(shù)量的權(quán)限。 ?
? Operator:操作。表明對(duì)What的How ? 操作。 ?
? 說明: ?
? User:與 ? Role ? 相關(guān),用戶僅僅是純粹的用戶,權(quán)限是被分離出去了的。User是不能與 ? Privilege ? 直接相關(guān)的,User ? 要擁有對(duì)某種資源的權(quán)限,必須通過Role去關(guān)聯(lián)。解決 ? Who ? 的問題。 ?
? Resource:就是系統(tǒng)的資源,比如部門新聞,文檔等各種可以被提供給用戶訪問的對(duì)象。資源可以反向包含自身,即樹狀結(jié)構(gòu),每一個(gè)資源節(jié)點(diǎn)可以與若干指定權(quán)限類別相關(guān)可定義是否將其權(quán)限應(yīng)用于子節(jié)點(diǎn)。 ?
? Privilege:是Resource ? Related的權(quán)限。就是指,這個(gè)權(quán)限是綁定在特定的資源實(shí)例上的。比如說部門新聞的發(fā)布權(quán)限,叫做"部門新聞發(fā)布權(quán)限"。這就表明,該P(yáng)rivilege是一個(gè)發(fā)布權(quán)限,而且是針對(duì)部門新聞這種資源的一種發(fā)布權(quán)限。Privilege是由Creator在做開發(fā)時(shí)就確定的。權(quán)限,包括系統(tǒng)定義權(quán)限和用戶自定義權(quán)限用戶自定義權(quán)限之間可以指定排斥和包含關(guān)系(如:讀取,修改,管理三個(gè)權(quán)限,管理 ? 權(quán)限 ? 包含 ? 前兩種權(quán)限)。Privilege ? 如"刪除" ? 是一個(gè)抽象的名詞,當(dāng)它不與任何具體的 ? Object ? 或 ? Resource ? 綁定在一起時(shí)是沒有任何意義的。拿新聞發(fā)布來說,發(fā)布是一種權(quán)限,但是只說發(fā)布它是毫無意義的。因?yàn)椴恢腊l(fā)布可以操作的對(duì)象是什么。只有當(dāng)發(fā)布與新聞結(jié)合在一起時(shí),才會(huì)產(chǎn)生真正的 ? Privilege。這就是 ? Privilege ? Instance。權(quán)限系統(tǒng)根據(jù)需求的不同可以延伸生很多不同的版本。 ?
? Role:是粗粒度和細(xì)粒度(業(yè)務(wù)邏輯)的接口,一個(gè)基于粗粒度控制的權(quán)限框架軟件,對(duì)外的接口應(yīng)該是Role,具體業(yè)務(wù)實(shí)現(xiàn)可以直接繼承或拓展豐富Role的內(nèi)容,Role不是如同User或Group的具體實(shí)體,它是接口概念,抽象的通稱。 ?
? Group:用戶組,權(quán)限分配的單位與載體。權(quán)限不考慮分配給特定的用戶。組可以包括組(以實(shí)現(xiàn)權(quán)限的繼承)。組可以包含用戶,組內(nèi)用戶繼承組的權(quán)限。Group要實(shí)現(xiàn)繼承。即在創(chuàng)建時(shí)必須要指定該Group的Parent是什么Group。在粗粒度控制上,可以認(rèn)為,只要某用戶直接或者間接的屬于某個(gè)Group那么它就具備這個(gè)Group的所有操作許可。細(xì)粒度控制上,在業(yè)務(wù)邏輯的判斷中,User僅應(yīng)關(guān)注其直接屬于的Group,用來判斷是否“同組” ? 。Group是可繼承的,對(duì)于一個(gè)分級(jí)的權(quán)限實(shí)現(xiàn),某個(gè)Group通過“繼承”就已經(jīng)直接獲得了其父Group所擁有的所有“權(quán)限集合”,對(duì)這個(gè)Group而言,需要與權(quán)限建立直接關(guān)聯(lián)的,僅是它比起其父Group需要“擴(kuò)展”的那部分權(quán)限。子組繼承父組的所有權(quán)限,規(guī)則來得更簡(jiǎn)單,同時(shí)意味著管理更容易。為了更進(jìn)一步實(shí)現(xiàn)權(quán)限的繼承,最直接的就是在Group上引入“父子關(guān)系”。 ?
? User與Group是多對(duì)多的關(guān)系。即一個(gè)User可以屬于多個(gè)Group之中,一個(gè)Group可以包括多個(gè)User。子Group與父Group是多對(duì)一的關(guān)系。Operator某種意義上類似于Resource ? + ? Privilege概念,但這里的Resource僅包括Resource ? Type不表示Resource ? Instance。Group ? 可以直接映射組織結(jié)構(gòu),Role ? 可以直接映射組織結(jié)構(gòu)中的業(yè)務(wù)角色,比較直觀,而且也足夠靈活。Role對(duì)系統(tǒng)的貢獻(xiàn)實(shí)質(zhì)上就是提供了一個(gè)比較粗顆粒的分配單位。 ?
? Group與Operator是多對(duì)多的關(guān)系。各概念的關(guān)系圖示如下: ?
? 解釋: ?
? Operator的定義包括了Resource ? Type和Method概念。即,What和How的概念。之所以將What和How綁定在一起作為一個(gè)Operator概念而不是分開建模再建立關(guān)聯(lián),這是因?yàn)楹芏嗟腍ow對(duì)于某What才有意義。比如,發(fā)布操作對(duì)新聞對(duì)象才有意義,對(duì)用戶對(duì)象則沒有意義。 ?
? How本身的意義也有所不同,具體來說,對(duì)于每一個(gè)What可以定義N種操作。比如,對(duì)于合同這類對(duì)象,可以定義創(chuàng)建操作、提交操作、檢查沖突操作等。可以認(rèn)為,How概念對(duì)應(yīng)于每一個(gè)商業(yè)方法。其中,與具體用戶身份相關(guān)的操作既可以定義在操作的業(yè)務(wù)邏輯之中,也可以定義在操作級(jí)別。比如,創(chuàng)建者的瀏覽視圖與普通用戶的瀏覽視圖要求內(nèi)容不同。既可以在外部定義兩個(gè)操作方法,也可以在一個(gè)操作方法的內(nèi)部根據(jù)具體邏輯進(jìn)行處理。具體應(yīng)用哪一種方式應(yīng)依據(jù)實(shí)際情況進(jìn)行處理。
?
這樣的架構(gòu),應(yīng)能在易于理解和管理的情況下,滿足絕大部分粗粒度權(quán)限控制的功能需要。但是除了粗粒度權(quán)限,系統(tǒng)中必然還會(huì)包括無數(shù)對(duì)具體Instance的細(xì)粒度權(quán)限。這些問題,被留給業(yè)務(wù)邏輯來解決,這樣的考慮基于以下兩點(diǎn): ?
? 一方面,細(xì)粒度的權(quán)限判斷必須要在資源上建模權(quán)限分配的支持信息才可能得以實(shí)現(xiàn)。比如,如果要求創(chuàng)建者和普通用戶看到不同的信息內(nèi)容,那么,資源本身應(yīng)該有其創(chuàng)建者的信息。另一方面,細(xì)粒度的權(quán)限常常具有相當(dāng)大的業(yè)務(wù)邏輯相關(guān)性。對(duì)不同的業(yè)務(wù)邏輯,常常意味著完全不同的權(quán)限判定原則和策略。相比之下,粗粒度的權(quán)限更具通用性,將其實(shí)現(xiàn)為一個(gè)架構(gòu),更有重用價(jià)值;而將細(xì)粒度的權(quán)限判斷實(shí)現(xiàn)為一個(gè)架構(gòu)級(jí)別的東西就顯得繁瑣,而且不是那么的有必要,用定制的代碼來實(shí)現(xiàn)就更簡(jiǎn)潔,更靈活。 ?
? 所以細(xì)粒度控制應(yīng)該在底層解決,Resource在實(shí)例化的時(shí)候,必需指定Owner和GroupPrivilege在對(duì)Resource進(jìn)行操作時(shí)也必然會(huì)確定約束類型:究竟是OwnerOK還是GroupOK還是AllOK。Group應(yīng)和Role嚴(yán)格分離User和Group是多對(duì)多的關(guān)系,Group只用于對(duì)用戶分類,不包含任何Role的意義;Role只授予User,而不是Group。如果用戶需要還沒有的多種Privilege的組合,必須新增Role。Privilege必須能夠訪問Resource,同時(shí)帶User參數(shù),這樣權(quán)限控制就完備了。 ?
? 思想: ?
? 權(quán)限系統(tǒng)的核心由以下三部分構(gòu)成:1.創(chuàng)造權(quán)限,2.分配權(quán)限,3.使用權(quán)限,然后,系統(tǒng)各部分的主要參與者對(duì)照如下:1.創(chuàng)造權(quán)限 ? - ? Creator創(chuàng)造,2.分配權(quán)限 ? - ? Administrator ? 分配,3.使用權(quán)限 ? - ? User: ?
? 1. ? Creator ? 創(chuàng)造 ? Privilege, ? Creator ? 在設(shè)計(jì)和實(shí)現(xiàn)系統(tǒng)時(shí)會(huì)劃分,一個(gè)子系統(tǒng)或稱為模塊,應(yīng)該有哪些權(quán)限。這里完成的是 ? Privilege ? 與 ? Resource ? 的對(duì)象聲明,并沒有真正將 ? Privilege ? 與具體Resource ? 實(shí)例聯(lián)系在一起,形成Operator。 ?
? 2. ? Administrator ? 指定 ? Privilege ? 與 ? Resource ? Instance ? 的關(guān)聯(lián)。在這一步, ? 權(quán)限真正與資源實(shí)例聯(lián)系到了一起, ? 產(chǎn)生了Operator(Privilege ? Instance)。Administrator利用Operator這個(gè)基本元素,來創(chuàng)造他理想中的權(quán)限模型。如,創(chuàng)建角色,創(chuàng)建用戶組,給用戶組分配用戶,將用戶組與角色關(guān)聯(lián)等等...這些操作都是由 ? Administrator ? 來完成的。 ?
? 3. ? User ? 使用 ? Administrator ? 分配給的權(quán)限去使用各個(gè)子系統(tǒng)。Administrator ? 是用戶,在他的心目中有一個(gè)比較適合他管理和維護(hù)的權(quán)限模型。于是,程序員只要回答一個(gè)問題,就是什么權(quán)限可以訪問什么資源,也就是前面說的 ? Operator。程序員提供 ? Operator ? 就意味著給系統(tǒng)穿上了盔甲。Administrator ? 就可以按照他的意愿來建立他所希望的權(quán)限框架可以自行增加,刪除,管理Resource和Privilege之間關(guān)系。可以自行設(shè)定用戶User和角色Role的對(duì)應(yīng)關(guān)系。(如果將 ? Creator看作是 ? Basic ? 的發(fā)明者, ? Administrator ? 就是 ? Basic ? 的使用者,他可以做一些腳本式的編程) ? Operator是這個(gè)系統(tǒng)中最關(guān)鍵的部分,它是一個(gè)紐帶,一個(gè)系在Programmer,Administrator,User之間的紐帶。 ?
? 用一個(gè)功能模塊來舉例子。 ?
? 一.建立角色功能并做分配: ?
? 1.如果現(xiàn)在要做一個(gè)員工管理的模塊(即Resources),這個(gè)模塊有三個(gè)功能,分別是:增加,修改,刪除。給這三個(gè)功能各自分配一個(gè)ID,這個(gè)ID叫做功能代號(hào): ?
? Emp_addEmp,Emp_deleteEmp,Emp_updateEmp。 ?
? 2.建立一個(gè)角色(Role),把上面的功能代碼加到這個(gè)角色擁有的權(quán)限中,并保存到數(shù)據(jù)庫(kù)中。角色包括系統(tǒng)管理員,測(cè)試人員等。 ?
? 3.建立一個(gè)員工的賬號(hào),并把一種或幾種角色賦給這個(gè)員工。比如說這個(gè)員工既可以是公司管理人員,也可以是測(cè)試人員等。這樣他登錄到系統(tǒng)中將會(huì)只看到他擁有權(quán)限的那些模塊。 ?
? 二.把身份信息加到Session中。 ?
? 登錄時(shí),先到數(shù)據(jù)庫(kù)中查找是否存在這個(gè)員工,如果存在,再根據(jù)員工的sn查找員工的權(quán)限信息,把員工所有的權(quán)限信息都入到一個(gè)Hashmap中,比如就把上面的Emp_addEmp等放到這個(gè)Hashmap中。然后把Hashmap保存在一個(gè)UserInfoBean中。最后把這個(gè)UserInfoBean放到Session中,這樣在整個(gè)程序的運(yùn)行過程中,系統(tǒng)隨時(shí)都可以取得這個(gè)用戶的身份信息。 ?
? 三.根據(jù)用戶的權(quán)限做出不同的顯示。 ?
? 可以對(duì)比當(dāng)前員工的權(quán)限和給這個(gè)菜單分配的“功能ID”判斷當(dāng)前用戶是否有打開這個(gè)菜單的權(quán)限。例如:如果保存員工權(quán)限的Hashmap中沒有這三個(gè)ID的任何一個(gè),那這個(gè)菜單就不會(huì)顯示,如果員工的Hashmap中有任何一個(gè)ID,那這個(gè)菜單都會(huì)顯示。 ? ?
? 對(duì)于一個(gè)新聞系統(tǒng)(Resouce),假設(shè)它有這樣的功能(Privilege):查看,發(fā)布,刪除,修改;假設(shè)對(duì)于刪除,有"新聞系統(tǒng)管理者只能刪除一月前發(fā)布的,而超級(jí)管理員可刪除所有的這樣的限制,這屬于業(yè)務(wù)邏輯(Business ? logic),而不屬于用戶權(quán)限范圍。也就是說權(quán)限負(fù)責(zé)有沒有刪除的Permission,至于能刪除哪些內(nèi)容應(yīng)該根據(jù)UserRole ? or ? UserGroup來決定(當(dāng)然給UserRole ? or ? UserGroup分配權(quán)限時(shí)就應(yīng)該包含上面兩條業(yè)務(wù)邏輯)。 ?
? 一個(gè)用戶可以擁有多種角色,但同一時(shí)刻用戶只能用一種角色進(jìn)入系統(tǒng)。角色的劃分方法可以根據(jù)實(shí)際情況劃分,按部門或機(jī)構(gòu)進(jìn)行劃分的,至于角色擁有多少權(quán)限,這就看系統(tǒng)管理員賦給他多少的權(quán)限了。用戶—角色—權(quán)限的關(guān)鍵是角色。用戶登錄時(shí)是以用戶和角色兩種屬性進(jìn)行登錄的(因?yàn)橐粋€(gè)用戶可以擁有多種角色,但同一時(shí)刻只能扮演一種角色),根據(jù)角色得到用戶的權(quán)限,登錄后進(jìn)行初始化。這其中的技巧是同一時(shí)刻某一用戶只能用一種角色進(jìn)行登錄。 ?
? 針對(duì)不同的“角色”動(dòng)態(tài)的建立不同的組,每個(gè)項(xiàng)目建立一個(gè)單獨(dú)的Group,對(duì)于新的項(xiàng)目,建立新的 ? Group ? 即可。在權(quán)限判斷部分,應(yīng)在商業(yè)方法上予以控制。比如:不同用戶的“操作能力”是不同的(粗粒度的控制應(yīng)能滿足要求),不同用戶的“可視區(qū)域”是不同的(體現(xiàn)在對(duì)被操作的對(duì)象的權(quán)限數(shù)據(jù),是否允許當(dāng)前用戶訪問,這需要對(duì)業(yè)務(wù)數(shù)據(jù)建模的時(shí)候考慮權(quán)限控制需要)。???
?
擴(kuò)展性: ?
? 有了用戶/權(quán)限管理的基本框架,Who(User/Group)的概念是不會(huì)經(jīng)常需要擴(kuò)展的。變化的可能是系統(tǒng)中引入新的 ? What ? (新的Resource類型)或者新的How(新的操作方式)。那在三個(gè)基本概念中,僅在Permission上進(jìn)行擴(kuò)展是不夠的。這樣的設(shè)計(jì)中Permission實(shí)質(zhì)上解決了How ? 的問題,即表示了“怎樣”的操作。那么這個(gè)“怎樣”是在哪一個(gè)層次上的定義呢?將Permission定義在“商業(yè)方法”級(jí)別比較合適。比如,發(fā)布、購(gòu)買、取消。每一個(gè)商業(yè)方法可以意味著用戶進(jìn)行的一個(gè)“動(dòng)作”。定義在商業(yè)邏輯的層次上,一方面保證了數(shù)據(jù)訪問代碼的“純潔性”,另一方面在功能上也是“足夠”的。也就是說,對(duì)更低層次,能自由的訪問數(shù)據(jù),對(duì)更高層次,也能比較精細(xì)的控制權(quán)限。 ?
? 確定了Permission定義的合適層次,更進(jìn)一步,能夠發(fā)現(xiàn)Permission實(shí)際上還隱含了What的概念。也就是說,對(duì)于What的How操作才會(huì)是一個(gè)完整的Operator。比如,“發(fā)布”操作,隱含了“信息”的“發(fā)布”概念,而對(duì)于“商品”而言發(fā)布操作是沒有意義的。同樣的,“購(gòu)買”操作,隱含了“商品”的“購(gòu)買”概念。這里的綁定還體現(xiàn)在大量通用的同名的操作上,比如,需要區(qū)分“商品的刪除”與“信息的刪除”這兩個(gè)同名為“刪除”的不同操作。 ?
? 提供權(quán)限系統(tǒng)的擴(kuò)展能力是在Operator ? (Resource ? + ? Permission)的概念上進(jìn)行擴(kuò)展。Proxy ? 模式是一個(gè)非常合適的實(shí)現(xiàn)方式。實(shí)現(xiàn)大致如下:在業(yè)務(wù)邏輯層(EJB ? Session ? Facade ? [Stateful ? SessionBean]中),取得該商業(yè)方法的Methodname,再根據(jù)Classname和 ? Methodname ? 檢索Operator ? 數(shù)據(jù),然后依據(jù)這個(gè)Operator信息和Stateful中保存的User信息判斷當(dāng)前用戶是否具備該方法的操作權(quán)限。 ?
? 應(yīng)用在 ? EJB ? 模式下,可以定義一個(gè)很明確的 ? Business層次,而一個(gè)Business ? 可能意味著不同的視圖,當(dāng)多個(gè)視圖都對(duì)應(yīng)于一個(gè)業(yè)務(wù)邏輯的時(shí)候,比如,Swing ? Client以及 ? Jsp ? Client ? 訪問的是同一個(gè) ? EJB ? 實(shí)現(xiàn)的 ? Business。在 ? Business ? 層上應(yīng)用權(quán)限較能提供集中的控制能力。實(shí)際上,如果權(quán)限系統(tǒng)提供了查詢能力,那么會(huì)發(fā)現(xiàn),在視圖層次已經(jīng)可以不去理解權(quán)限,它只需要根據(jù)查詢結(jié)果控制界面就可以了。 ?
? 靈活性: ?
? Group和Role,只是一種輔助實(shí)現(xiàn)的手段,不是必需的。如果系統(tǒng)的Role很多,逐個(gè)授權(quán)違背了“簡(jiǎn)單,方便”的目的,那就引入Group,將權(quán)限相同的Role組成一個(gè)Group進(jìn)行集中授權(quán)。Role也一樣,是某一類Operator的集合,是為了簡(jiǎn)化針對(duì)多個(gè)Operator的操作。 ?
? Role把具體的用戶和組從權(quán)限中解放出來。一個(gè)用戶可以承擔(dān)不同的角色,從而實(shí)現(xiàn)授權(quán)的靈活性。當(dāng)然,Group也可以實(shí)現(xiàn)類似的功能。但實(shí)際業(yè)務(wù)中,Group劃分多以行政組織結(jié)構(gòu)或業(yè)務(wù)功能劃分;如果為了權(quán)限管理強(qiáng)行將一個(gè)用戶加入不同的組,會(huì)導(dǎo)致管理的復(fù)雜性。 ?
? Domain的應(yīng)用。為了授權(quán)更靈活,可以將Where或者Scope抽象出來,稱之為Domain,真正的授權(quán)是在Domain的范圍內(nèi)進(jìn)行,具體的Resource將分屬于不同的Domain。比如:一個(gè)新聞機(jī)構(gòu)有國(guó)內(nèi)與國(guó)外兩大分支,兩大分支內(nèi)又都有不同的資源(體育類、生活類、時(shí)事政治類)。假如所有國(guó)內(nèi)新聞的權(quán)限規(guī)則都是一樣的,所有國(guó)外新聞的權(quán)限規(guī)則也相同。則可以建立兩個(gè)域,分別授權(quán),然后只要將各類新聞與不同的域關(guān)聯(lián),受域上的權(quán)限控制,從而使之簡(jiǎn)化。 ?
? 權(quán)限系統(tǒng)還應(yīng)該考慮將功能性的授權(quán)與資源性的授權(quán)分開。很多系統(tǒng)都只有對(duì)系統(tǒng)中的數(shù)據(jù)(資源)的維護(hù)有權(quán)限控制,但沒有對(duì)系統(tǒng)功能的權(quán)限控制。 ?
? 權(quán)限系統(tǒng)最好是可以分層管理而不是集中管理。大多客戶希望不同的部門能且僅能管理其部門內(nèi)部的事務(wù),而不是什么都需要一個(gè)集中的Administrator或Administrators組來管理。雖然你可以將不同部門的人都加入Administrators組,但他們的權(quán)限過大,可以管理整個(gè)系統(tǒng)資源而不是該部門資源。 ?
? 正向授權(quán)與負(fù)向授權(quán):正向授權(quán)在開始時(shí)假定主體沒有任何權(quán)限,然后根據(jù)需要授予權(quán)限,適合于權(quán)限要求嚴(yán)格的系統(tǒng)。負(fù)向授權(quán)在開始時(shí)假定主體有所有權(quán)限,然后將某些特殊權(quán)限收回。 ?
? 權(quán)限計(jì)算策略:系統(tǒng)中User,Group,Role都可以授權(quán),權(quán)限可以有正負(fù)向之分,在計(jì)算用戶的凈權(quán)限時(shí)定義一套策略。 ?
? 系統(tǒng)中應(yīng)該有一個(gè)集中管理權(quán)限的AccessService,負(fù)責(zé)權(quán)限的維護(hù)(業(yè)務(wù)管理員、安全管理模塊)與使用(最終用戶、各功能模塊),該AccessService在實(shí)現(xiàn)時(shí)要同時(shí)考慮一般權(quán)限與特殊權(quán)限。雖然在具體實(shí)現(xiàn)上可以有很多,比如用Proxy模式,但應(yīng)該使這些Proxy依賴于AccessService。各模塊功能中調(diào)用AccessService來檢查是否有相應(yīng)的權(quán)限。所以說,權(quán)限管理不是安全管理模塊自己一個(gè)人的事情,而是與系統(tǒng)各功能模塊都有關(guān)系。每個(gè)功能模塊的開發(fā)人員都應(yīng)該熟悉安全管理模塊,當(dāng)然,也要從業(yè)務(wù)上熟悉本模塊的安全規(guī)則。 ?
? 技術(shù)實(shí)現(xiàn): ?
? 1.表單式認(rèn)證,這是常用的,但用戶到達(dá)一個(gè)不被授權(quán)訪問的資源時(shí),Web容器就發(fā) ?
? 出一個(gè)html頁(yè)面,要求輸入用戶名和密碼。 ? ?
? 2.一個(gè)基于Servlet ? Sign ? in/Sign ? out來集中處理所有的Request,缺點(diǎn)是必須由應(yīng)用程序自己來處理。 ?
? 3.用Filter防止用戶訪問一些未被授權(quán)的資源,F(xiàn)ilter會(huì)截取所有Request/Response, ?
? 然后放置一個(gè)驗(yàn)證通過的標(biāo)識(shí)在用戶的Session中,然后Filter每次依靠這個(gè)標(biāo)識(shí)來決定是否放行Response。 ?
? 這個(gè)模式分為: ?
? Gatekeeper ? :采取Filter或統(tǒng)一Servlet的方式。 ?
? Authenticator: ? 在Web中使用JAAS自己來實(shí)現(xiàn)。 ?
? 用戶資格存儲(chǔ)LDAP或數(shù)據(jù)庫(kù): ?
? 1. ? Gatekeeper攔截檢查每個(gè)到達(dá)受保護(hù)的資源。首先檢查這個(gè)用戶是否有已經(jīng)創(chuàng)建 ?
? 好的Login ? Session,如果沒有,Gatekeeper ? 檢查是否有一個(gè)全局的和Authenticator相關(guān)的session? ?
? 2. ? 如果沒有全局的session,這個(gè)用戶被導(dǎo)向到Authenticator的Sign-on ? 頁(yè)面, ?
? 要求提供用戶名和密碼。 ?
? 3. ? Authenticator接受用戶名和密碼,通過用戶的資格系統(tǒng)驗(yàn)證用戶。 ?
? 4. ? 如果驗(yàn)證成功,Authenticator將創(chuàng)建一個(gè)全局Login ? session,并且導(dǎo)向Gatekeeper ?
? 來為這個(gè)用戶在他的web應(yīng)用中創(chuàng)建一個(gè)Login ? Session。 ?
? 5. ? Authenticator和Gatekeepers聯(lián)合分享Cookie,或者使用Tokens在Query字符里。
但凡涉及多用戶不同權(quán)限的網(wǎng)絡(luò)或者單機(jī)程序,都會(huì)有權(quán)限管理的問題,比較突出的是MIS系統(tǒng)。 ? ?
? ?
? 下面我要說的是MIS系統(tǒng)權(quán)限管理的數(shù)據(jù)庫(kù)設(shè)計(jì)及實(shí)現(xiàn),當(dāng)然,這些思路也可以推廣開來應(yīng)用,比如說在BBS中用來管理不同級(jí)別的用戶權(quán)限。 ? ?
? ?
? 權(quán)限設(shè)計(jì)通常包括數(shù)據(jù)庫(kù)設(shè)計(jì)、應(yīng)用程序接口(API)設(shè)計(jì)、程序?qū)崿F(xiàn)三個(gè)部分。 ? ?
? ?
? 這三個(gè)部分相互依存,密不可分,要實(shí)現(xiàn)完善的權(quán)限管理體系,必須考慮到每一個(gè)環(huán)節(jié)可行性與復(fù)雜程度甚至執(zhí)行效率。 ? ?
? ?
? 我們將權(quán)限分類,首先是針對(duì)數(shù)據(jù)存取的權(quán)限,通常有錄入、瀏覽、修改、刪除四種,其次是功能,它可以包括例如統(tǒng)計(jì)等所有非直接數(shù)據(jù)存取操作,另外,我們還可能對(duì)一些關(guān)鍵數(shù)據(jù)表某些字段的存取進(jìn)行限制。除此,我想不出還有另外種類的權(quán)限類別。 ? ?
? ?
? 完善的權(quán)限設(shè)計(jì)應(yīng)該具有充分的可擴(kuò)展性,也就是說,系統(tǒng)增加了新的其它功能不應(yīng)該對(duì)整個(gè)權(quán)限管理體系帶來較大的變化,要達(dá)到這個(gè)目的,首先是數(shù)據(jù)庫(kù)設(shè)計(jì)合理,其次是應(yīng)用程序接口規(guī)范。 ? ?
? ?
? 我們先討論數(shù)據(jù)庫(kù)設(shè)計(jì)。通常我們使用關(guān)系數(shù)據(jù)庫(kù),這里不討論基于Lotus產(chǎn)品的權(quán)限管理。 ? ?
? ?
? 權(quán)限表及相關(guān)內(nèi)容大體可以用六個(gè)表來描述,如下: ? ?
? 1 ? 角色(即用戶組)表:包括三個(gè)字段,ID,角色名,對(duì)該角色的描述; ? ?
? 2 ? 用戶表:包括三個(gè)或以上字段,ID,用戶名,對(duì)該用戶的描述,其它(如地址、電話等信息); ? ?
? 3 ? 角色-用戶對(duì)應(yīng)表:該表記錄用戶與角色之間的對(duì)應(yīng)關(guān)系,一個(gè)用戶可以隸屬于多個(gè)角色,一個(gè)角色組也可擁有多個(gè)用戶。包括三個(gè)字段,ID,角色I(xiàn)D,用戶ID; ? ?
? 4 ? 限制內(nèi)容列表:該表記錄所有需要加以權(quán)限區(qū)分限制的數(shù)據(jù)表、功能和字段等內(nèi)容及其描述,包括三個(gè)字段,ID,名稱,描述; ? ?
? 5 ? 權(quán)限列表:該表記錄所有要加以控制的權(quán)限,如錄入、修改、刪除、執(zhí)行等,也包括三個(gè)字段,ID,名稱,描述; ? ?
? 6 ? 權(quán)限-角色-用戶對(duì)應(yīng)表:一般情況下,我們對(duì)角色/用戶所擁有的權(quán)限做如下規(guī)定,角色擁有明令允許的權(quán)限,其它一律禁止,用戶繼承所屬角色的全部權(quán)限,在此范圍內(nèi)的權(quán)限除明令禁止外全部允許,范圍外權(quán)限除明令允許外全部禁止。該表的設(shè)計(jì)是權(quán)限管理的重點(diǎn),設(shè)計(jì)的思路也很多,可以說各有千秋,不能生搬硬套說某種方法好。對(duì)此,我的看法是就個(gè)人情況,找自己覺得合適能解決問題的用。 ? ?
? ?
? 先說第一種也是最容易理解的方法,設(shè)計(jì)五個(gè)字段:ID,限制內(nèi)容ID,權(quán)限ID,角色/用戶類型(布爾型字段,用來描述一條記錄記錄的是角色權(quán)限還是用戶權(quán)限),角色/用戶ID,權(quán)限類型(布爾型字段,用來描述一條記錄表示允許還是禁止) ? ?
? ?
? 好了,有這六個(gè)表,根據(jù)表六,我們就可以知道某個(gè)角色/用戶到底擁有/禁止某種權(quán)限。 ? ?
? ?
? 或者說,這么設(shè)計(jì)已經(jīng)足夠了,我們完全實(shí)現(xiàn)了所需要的功能:可以對(duì)角色和用戶分別進(jìn)行權(quán)限定制,也具有相當(dāng)?shù)目蓴U(kuò)展性,比如說增加了新功能,我們只需要添加一條或者幾條記錄就可以,同時(shí)應(yīng)用程序接口也無須改動(dòng),具有相當(dāng)?shù)目尚行浴5牵诔绦驅(qū)崿F(xiàn)的過程中,我們發(fā)現(xiàn),使用這種方法并不是十分科學(xué),例如瀏覽某個(gè)用戶所擁有的權(quán)限時(shí),需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行多次(甚至是遞歸)查詢,極不方便。于是我們需要想其它的辦法。使用過Unix系統(tǒng)的人們都知道,Unix文件系統(tǒng)將對(duì)文件的操作權(quán)限分為三種:讀、寫和執(zhí)行,分別用1、2、4三個(gè)代碼標(biāo)識(shí),對(duì)用戶同時(shí)具有讀寫權(quán)限的文件被記錄為3,即1+2。我們也可以用類似的辦法來解決這個(gè)問題。初步的想法是修改權(quán)限列表,加入一個(gè)字段:標(biāo)識(shí)碼,例如,我們可以將錄入權(quán)限標(biāo)識(shí)為1,瀏覽權(quán)限標(biāo)識(shí)為2,修改權(quán)限標(biāo)識(shí)為4,刪除權(quán)限標(biāo)識(shí)為8,執(zhí)行權(quán)限標(biāo)識(shí)為16,這樣,我們通過權(quán)限累加的辦法就可以輕易的將原本要分為幾條記錄描述的權(quán)限放在一起了,例如,假定某用戶ID為1,庫(kù)存表對(duì)應(yīng)的限制內(nèi)容ID為2,同時(shí)規(guī)定角色類型為0、用戶類型為1,我們就可以將該用戶具有錄入、瀏覽、修改、刪除庫(kù)存表的權(quán)限描述為:2,15,1,1。 ? ?
? ?
? 確實(shí)很簡(jiǎn)單,不是嗎?甚至還有更過激的辦法,將限制內(nèi)容列表也加上一列,定義好標(biāo)識(shí)碼,這樣,我們甚至可以用簡(jiǎn)單的一條記錄描述某個(gè)用戶具有的對(duì)全部?jī)?nèi)容所具有的全部權(quán)限了。當(dāng)然,這樣做的前提是限制內(nèi)容數(shù)量比較小,不然,呵呵,2的n次方遞增起來可是數(shù)量驚人,不容易解析的。 ? ?
? ?
? 從表面上看,上述方法足以達(dá)到實(shí)現(xiàn)功能、簡(jiǎn)化數(shù)據(jù)庫(kù)設(shè)計(jì)及實(shí)現(xiàn)的復(fù)雜度這個(gè)目的,但這樣做有個(gè)弊端,我們所涉及的權(quán)限列表不是相互獨(dú)立而是互相依賴的,比如說修改權(quán)限,其實(shí)是包含瀏覽權(quán)限的,例如,我們可能只是簡(jiǎn)單的設(shè)置用戶對(duì)庫(kù)存表存取的權(quán)限值為錄入+修改+刪除(1+4+8=13),但事實(shí)上,該用戶具有(1+2+4+8=15)的權(quán)限,也就是說,在這種方案中,13=15。于是當(dāng)我們調(diào)用API詢問某用戶是否具有瀏覽權(quán)限時(shí),就必須判斷該用戶是否具有對(duì)該數(shù)據(jù)表的修改權(quán)限,因此,如果不能在程序中固化權(quán)限之間的包含關(guān)系,就不能利用應(yīng)用程序接口簡(jiǎn)單的做出判斷。但這與我們的目的“充分的可擴(kuò)展性”矛盾。 ? ?
? ?
? 這個(gè)問題如何解決?我想到了另外一種設(shè)置標(biāo)識(shí)碼的方法,那就是利用素?cái)?shù)。我們不妨將錄入、瀏覽、修改、刪除、執(zhí)行的基本標(biāo)志碼定為2,3,5,7,11,當(dāng)遇到權(quán)限互相包含的時(shí)候,我們將它的標(biāo)識(shí)碼設(shè)定為兩個(gè)(或多個(gè))基本標(biāo)志碼的乘積,例如,可以將“修改”功能的標(biāo)志碼定為3*5=15,然后將所有的權(quán)限相乘,就得到了我們需要的最終權(quán)限標(biāo)識(shí)值。這樣,我們?cè)谠儐栍脩羰欠窬哂心稠?xiàng)權(quán)限的時(shí)候,只需要將最終的值分解成質(zhì)因子,例如,我們可以定義一個(gè)用戶具有錄入+修改+刪除庫(kù)存表的權(quán)限為 ? 2*15*7=2*3*5*7,即表示,該用戶具有了對(duì)庫(kù)存表錄入+瀏覽+修改+刪除權(quán)限。 ? ?
? ?
? 當(dāng)然,對(duì)權(quán)限列表我們使用上述方法的前提是權(quán)限列表記錄條數(shù)不會(huì)太多并且關(guān)系不是十分復(fù)雜,否則,光是解析權(quán)限代碼就要機(jī)器忽悠半宿:) ? ?
? ?
? 我希望以上的分析是正確且有效的(事實(shí)上,我也用這些的方法在不止一套系統(tǒng)中實(shí)現(xiàn)),但無論如何,我覺得如此實(shí)現(xiàn)權(quán)限管理,只是考慮了數(shù)據(jù)庫(kù)設(shè)計(jì)和應(yīng)用程序接口兩部分內(nèi)容,對(duì)于實(shí)現(xiàn),還是顯得很費(fèi)勁。因此,我懇請(qǐng)有過類似設(shè)計(jì)、實(shí)現(xiàn)經(jīng)驗(yàn)的同志們提出建設(shè)性的意見和修改建議。 ? ?
? ?
? 另外,關(guān)于數(shù)據(jù)庫(kù)設(shè)計(jì)的思路還有使用二維表的,這將在以后的時(shí)間里討論,關(guān)于應(yīng)用程序接口的設(shè)計(jì)和實(shí)現(xiàn)我也將在利用另外篇幅和大家共同探討,代碼將用類C語(yǔ)法實(shí)現(xiàn)(我不喜歡pascal,抱歉)?????
????
?
? 權(quán)限往往是一個(gè)極其復(fù)雜的問題,但也可簡(jiǎn)單表述為這樣的邏輯表達(dá)式:判斷“Who對(duì)What(Which)進(jìn)行How的操作”的邏輯表達(dá)式是否為真。針對(duì)不同的
? 目標(biāo): ?
? 直觀,因?yàn)橄到y(tǒng)最終會(huì)由最終用戶來維護(hù),權(quán)限分配的直觀和容易理解,顯得比較重要,系統(tǒng)不辭勞苦的實(shí)現(xiàn)了組的繼承,除了功能的必須,更主要的就是因?yàn)樗銐蛑庇^。 ?
? 簡(jiǎn)單,包括概念數(shù)量上的簡(jiǎn)單和意義上的簡(jiǎn)單還有功能上的簡(jiǎn)單。想用一個(gè)權(quán)限系統(tǒng)解決所有的權(quán)限問題是不現(xiàn)實(shí)的。設(shè)計(jì)中將常常變化的“定制”特點(diǎn)比較強(qiáng)的部分判斷為業(yè)務(wù)邏輯,而將常常相同的“通用”特點(diǎn)比較強(qiáng)的部分判斷為權(quán)限邏輯就是基于這樣的思路。 ?
? 擴(kuò)展,采用可繼承在擴(kuò)展上的困難。的Group概念在支持權(quán)限以組方式定義的同時(shí)有效避免了重定義時(shí) ?
? 現(xiàn)狀: ?
? 對(duì)于在企業(yè)環(huán)境中的訪問控制
? 1.自主型訪問控制方法。目前在我國(guó)的大多數(shù)的信息系統(tǒng)中的訪問控制模塊中基本是借助于自主型訪問控制方法中的訪問控制列表(ACLs)。 ?
? 2.強(qiáng)制型訪問控制方法。用于多層次安全級(jí)別的
? 3.基于角色的訪問控制方法(RBAC)。是目前公認(rèn)的解決大型企業(yè)的統(tǒng)一資源訪問控制的有效方法。其顯著的兩大特征是:1.減小授權(quán)管理的復(fù)雜性,降低管理開銷。2.靈活地支持企業(yè)的安全策略,并對(duì)企業(yè)的變化有很大的伸縮性。 ?
? 名詞: ?
? 粗粒度:表示類別級(jí),即僅考慮對(duì)象的類別(the ? type ? of ? object),不考慮對(duì)象的某個(gè)特 ?
? 定實(shí)例。比如,用戶管理中,創(chuàng)建、刪除,對(duì)所有的用戶都一視同仁,并不區(qū)分操作的具體對(duì)象實(shí)例。 ?
? 細(xì)粒度:表示實(shí)例級(jí),即需要考慮具體對(duì)象的實(shí)例(the ? instance ? of ? object),當(dāng)然,細(xì) ?
? 粒度是在考慮粗粒度的對(duì)象類別之后才再考慮特定實(shí)例。比如,合同管理中,列表、刪除,需要區(qū)分該合同實(shí)例是否為當(dāng)前用戶所創(chuàng)建。 ?
? 原則: ?
? 權(quán)限邏輯配合業(yè)務(wù)邏輯。即權(quán)限系統(tǒng)以為業(yè)務(wù)邏輯提供服務(wù)為目標(biāo)。相當(dāng)多細(xì)粒度的權(quán)限問題因其極其獨(dú)特而不具通用意義,它們也能被理解為是“業(yè)務(wù)邏輯”的一部分。比如,要求:“合同資源只能被它的創(chuàng)建者刪除,與創(chuàng)建者同組的用戶可以修改,所有的用戶能夠?yàn)g覽”。這既可以認(rèn)為是一個(gè)細(xì)粒度的權(quán)限問題,也可以認(rèn)為是一個(gè)業(yè)務(wù)邏輯問題。在這里它是業(yè)務(wù)邏輯問題,在整個(gè)權(quán)限系統(tǒng)的架構(gòu)設(shè)計(jì)之中不予過多考慮。當(dāng)然,權(quán)限系統(tǒng)的架構(gòu)也必須要能支持這樣的控制判斷。或者說,系統(tǒng)提供足夠多但不是完全的控制
? 需要再次強(qiáng)調(diào)的是,這里表述的權(quán)限系統(tǒng)僅是一個(gè)“不完全”的權(quán)限系統(tǒng),即,它不提供所有關(guān)于權(quán)限的問題的解決方法。它提供一個(gè)基礎(chǔ),并解決那些具有“共性”的(或者說粗粒度的)部分。在這個(gè)基礎(chǔ)之上,根據(jù)“業(yè)務(wù)邏輯”的獨(dú)特權(quán)限需求,編碼實(shí)現(xiàn)剩余部分(或者說細(xì)粒度的)部分,才算完整。回到權(quán)限的問題公式,通用的設(shè)計(jì)僅解決了Who+What+How ? 的問題,其他的權(quán)限問題留給業(yè)務(wù)邏輯解決。 ?
? 概念: ?
? Who:權(quán)限的擁用者或主體(Principal、User、Group、Role、Actor等等) ?
? What:權(quán)限針對(duì)的對(duì)象或資源(Resource、Class)。 ?
? How:具體的權(quán)限(Privilege, ? 正向授權(quán)與負(fù)向授權(quán))。 ?
? Role:是角色,擁有一定數(shù)量的權(quán)限。 ?
? Operator:操作。表明對(duì)What的How ? 操作。 ?
? 說明: ?
? User:與 ? Role ? 相關(guān),用戶僅僅是純粹的用戶,權(quán)限是被分離出去了的。User是不能與 ? Privilege ? 直接相關(guān)的,User ? 要擁有對(duì)某種資源的權(quán)限,必須通過Role去關(guān)聯(lián)。解決 ? Who ? 的問題。 ?
? Resource:就是系統(tǒng)的資源,比如部門新聞,文檔等各種可以被提供給用戶訪問的對(duì)象。資源可以反向包含自身,即樹狀結(jié)構(gòu),每一個(gè)資源節(jié)點(diǎn)可以與若干指定權(quán)限類別相關(guān)可定義是否將其權(quán)限應(yīng)用于子節(jié)點(diǎn)。 ?
? Privilege:是Resource ? Related的權(quán)限。就是指,這個(gè)權(quán)限是綁定在特定的資源實(shí)例上的。比如說部門新聞的發(fā)布權(quán)限,叫做"部門新聞發(fā)布權(quán)限"。這就表明,該P(yáng)rivilege是一個(gè)發(fā)布權(quán)限,而且是針對(duì)部門新聞這種資源的一種發(fā)布權(quán)限。Privilege是由Creator在做開發(fā)時(shí)就確定的。權(quán)限,包括系統(tǒng)定義權(quán)限和用戶自定義權(quán)限用戶自定義權(quán)限之間可以指定排斥和包含關(guān)系(如:讀取,修改,管理三個(gè)權(quán)限,管理 ? 權(quán)限 ? 包含 ? 前兩種權(quán)限)。Privilege ? 如"刪除" ? 是一個(gè)抽象的名詞,當(dāng)它不與任何具體的 ? Object ? 或 ? Resource ? 綁定在一起時(shí)是沒有任何意義的。拿新聞發(fā)布來說,發(fā)布是一種權(quán)限,但是只說發(fā)布它是毫無意義的。因?yàn)椴恢腊l(fā)布可以操作的對(duì)象是什么。只有當(dāng)發(fā)布與新聞結(jié)合在一起時(shí),才會(huì)產(chǎn)生真正的 ? Privilege。這就是 ? Privilege ? Instance。權(quán)限系統(tǒng)根據(jù)需求的不同可以延伸生很多不同的版本。 ?
? Role:是粗粒度和細(xì)粒度(業(yè)務(wù)邏輯)的接口,一個(gè)基于粗粒度控制的權(quán)限框架軟件,對(duì)外的接口應(yīng)該是Role,具體業(yè)務(wù)實(shí)現(xiàn)可以直接繼承或拓展豐富Role的內(nèi)容,Role不是如同User或Group的具體實(shí)體,它是接口概念,抽象的通稱。 ?
? Group:用戶組,權(quán)限分配的單位與載體。權(quán)限不考慮分配給特定的用戶。組可以包括組(以實(shí)現(xiàn)權(quán)限的繼承)。組可以包含用戶,組內(nèi)用戶繼承組的權(quán)限。Group要實(shí)現(xiàn)繼承。即在創(chuàng)建時(shí)必須要指定該Group的Parent是什么Group。在粗粒度控制上,可以認(rèn)為,只要某用戶直接或者間接的屬于某個(gè)Group那么它就具備這個(gè)Group的所有操作許可。細(xì)粒度控制上,在業(yè)務(wù)邏輯的判斷中,User僅應(yīng)關(guān)注其直接屬于的Group,用來判斷是否“同組” ? 。Group是可繼承的,對(duì)于一個(gè)分級(jí)的權(quán)限實(shí)現(xiàn),某個(gè)Group通過“繼承”就已經(jīng)直接獲得了其父Group所擁有的所有“權(quán)限集合”,對(duì)這個(gè)Group而言,需要與權(quán)限建立直接關(guān)聯(lián)的,僅是它比起其父Group需要“擴(kuò)展”的那部分權(quán)限。子組繼承父組的所有權(quán)限,規(guī)則來得更簡(jiǎn)單,同時(shí)意味著管理更容易。為了更進(jìn)一步實(shí)現(xiàn)權(quán)限的繼承,最直接的就是在Group上引入“父子關(guān)系”。 ?
? User與Group是多對(duì)多的關(guān)系。即一個(gè)User可以屬于多個(gè)Group之中,一個(gè)Group可以包括多個(gè)User。子Group與父Group是多對(duì)一的關(guān)系。Operator某種意義上類似于Resource ? + ? Privilege概念,但這里的Resource僅包括Resource ? Type不表示Resource ? Instance。Group ? 可以直接映射組織結(jié)構(gòu),Role ? 可以直接映射組織結(jié)構(gòu)中的業(yè)務(wù)角色,比較直觀,而且也足夠靈活。Role對(duì)系統(tǒng)的貢獻(xiàn)實(shí)質(zhì)上就是提供了一個(gè)比較粗顆粒的分配單位。 ?
? Group與Operator是多對(duì)多的關(guān)系。各概念的關(guān)系圖示如下: ?
? 解釋: ?
? Operator的定義包括了Resource ? Type和Method概念。即,What和How的概念。之所以將What和How綁定在一起作為一個(gè)Operator概念而不是分開建模再建立關(guān)聯(lián),這是因?yàn)楹芏嗟腍ow對(duì)于某What才有意義。比如,發(fā)布操作對(duì)新聞對(duì)象才有意義,對(duì)用戶對(duì)象則沒有意義。 ?
? How本身的意義也有所不同,具體來說,對(duì)于每一個(gè)What可以定義N種操作。比如,對(duì)于合同這類對(duì)象,可以定義創(chuàng)建操作、提交操作、檢查沖突操作等。可以認(rèn)為,How概念對(duì)應(yīng)于每一個(gè)商業(yè)方法。其中,與具體用戶身份相關(guān)的操作既可以定義在操作的業(yè)務(wù)邏輯之中,也可以定義在操作級(jí)別。比如,創(chuàng)建者的瀏覽視圖與普通用戶的瀏覽視圖要求內(nèi)容不同。既可以在外部定義兩個(gè)操作方法,也可以在一個(gè)操作方法的內(nèi)部根據(jù)具體邏輯進(jìn)行處理。具體應(yīng)用哪一種方式應(yīng)依據(jù)實(shí)際情況進(jìn)行處理。
?
這樣的架構(gòu),應(yīng)能在易于理解和管理的情況下,滿足絕大部分粗粒度權(quán)限控制的功能需要。但是除了粗粒度權(quán)限,系統(tǒng)中必然還會(huì)包括無數(shù)對(duì)具體Instance的細(xì)粒度權(quán)限。這些問題,被留給業(yè)務(wù)邏輯來解決,這樣的考慮基于以下兩點(diǎn): ?
? 一方面,細(xì)粒度的權(quán)限判斷必須要在資源上建模權(quán)限分配的支持信息才可能得以實(shí)現(xiàn)。比如,如果要求創(chuàng)建者和普通用戶看到不同的信息內(nèi)容,那么,資源本身應(yīng)該有其創(chuàng)建者的信息。另一方面,細(xì)粒度的權(quán)限常常具有相當(dāng)大的業(yè)務(wù)邏輯相關(guān)性。對(duì)不同的業(yè)務(wù)邏輯,常常意味著完全不同的權(quán)限判定原則和策略。相比之下,粗粒度的權(quán)限更具通用性,將其實(shí)現(xiàn)為一個(gè)架構(gòu),更有重用價(jià)值;而將細(xì)粒度的權(quán)限判斷實(shí)現(xiàn)為一個(gè)架構(gòu)級(jí)別的東西就顯得繁瑣,而且不是那么的有必要,用定制的代碼來實(shí)現(xiàn)就更簡(jiǎn)潔,更靈活。 ?
? 所以細(xì)粒度控制應(yīng)該在底層解決,Resource在實(shí)例化的時(shí)候,必需指定Owner和GroupPrivilege在對(duì)Resource進(jìn)行操作時(shí)也必然會(huì)確定約束類型:究竟是OwnerOK還是GroupOK還是AllOK。Group應(yīng)和Role嚴(yán)格分離User和Group是多對(duì)多的關(guān)系,Group只用于對(duì)用戶分類,不包含任何Role的意義;Role只授予User,而不是Group。如果用戶需要還沒有的多種Privilege的組合,必須新增Role。Privilege必須能夠訪問Resource,同時(shí)帶User參數(shù),這樣權(quán)限控制就完備了。 ?
? 思想: ?
? 權(quán)限系統(tǒng)的核心由以下三部分構(gòu)成:1.創(chuàng)造權(quán)限,2.分配權(quán)限,3.使用權(quán)限,然后,系統(tǒng)各部分的主要參與者對(duì)照如下:1.創(chuàng)造權(quán)限 ? - ? Creator創(chuàng)造,2.分配權(quán)限 ? - ? Administrator ? 分配,3.使用權(quán)限 ? - ? User: ?
? 1. ? Creator ? 創(chuàng)造 ? Privilege, ? Creator ? 在設(shè)計(jì)和實(shí)現(xiàn)系統(tǒng)時(shí)會(huì)劃分,一個(gè)子系統(tǒng)或稱為模塊,應(yīng)該有哪些權(quán)限。這里完成的是 ? Privilege ? 與 ? Resource ? 的對(duì)象聲明,并沒有真正將 ? Privilege ? 與具體Resource ? 實(shí)例聯(lián)系在一起,形成Operator。 ?
? 2. ? Administrator ? 指定 ? Privilege ? 與 ? Resource ? Instance ? 的關(guān)聯(lián)。在這一步, ? 權(quán)限真正與資源實(shí)例聯(lián)系到了一起, ? 產(chǎn)生了Operator(Privilege ? Instance)。Administrator利用Operator這個(gè)基本元素,來創(chuàng)造他理想中的權(quán)限模型。如,創(chuàng)建角色,創(chuàng)建用戶組,給用戶組分配用戶,將用戶組與角色關(guān)聯(lián)等等...這些操作都是由 ? Administrator ? 來完成的。 ?
? 3. ? User ? 使用 ? Administrator ? 分配給的權(quán)限去使用各個(gè)子系統(tǒng)。Administrator ? 是用戶,在他的心目中有一個(gè)比較適合他管理和維護(hù)的權(quán)限模型。于是,程序員只要回答一個(gè)問題,就是什么權(quán)限可以訪問什么資源,也就是前面說的 ? Operator。程序員提供 ? Operator ? 就意味著給系統(tǒng)穿上了盔甲。Administrator ? 就可以按照他的意愿來建立他所希望的權(quán)限框架可以自行增加,刪除,管理Resource和Privilege之間關(guān)系。可以自行設(shè)定用戶User和角色Role的對(duì)應(yīng)關(guān)系。(如果將 ? Creator看作是 ? Basic ? 的發(fā)明者, ? Administrator ? 就是 ? Basic ? 的使用者,他可以做一些腳本式的編程) ? Operator是這個(gè)系統(tǒng)中最關(guān)鍵的部分,它是一個(gè)紐帶,一個(gè)系在Programmer,Administrator,User之間的紐帶。 ?
? 用一個(gè)功能模塊來舉例子。 ?
? 一.建立角色功能并做分配: ?
? 1.如果現(xiàn)在要做一個(gè)員工管理的模塊(即Resources),這個(gè)模塊有三個(gè)功能,分別是:增加,修改,刪除。給這三個(gè)功能各自分配一個(gè)ID,這個(gè)ID叫做功能代號(hào): ?
? Emp_addEmp,Emp_deleteEmp,Emp_updateEmp。 ?
? 2.建立一個(gè)角色(Role),把上面的功能代碼加到這個(gè)角色擁有的權(quán)限中,并保存到數(shù)據(jù)庫(kù)中。角色包括系統(tǒng)管理員,測(cè)試人員等。 ?
? 3.建立一個(gè)員工的賬號(hào),并把一種或幾種角色賦給這個(gè)員工。比如說這個(gè)員工既可以是公司管理人員,也可以是測(cè)試人員等。這樣他登錄到系統(tǒng)中將會(huì)只看到他擁有權(quán)限的那些模塊。 ?
? 二.把身份信息加到Session中。 ?
? 登錄時(shí),先到數(shù)據(jù)庫(kù)中查找是否存在這個(gè)員工,如果存在,再根據(jù)員工的sn查找員工的權(quán)限信息,把員工所有的權(quán)限信息都入到一個(gè)Hashmap中,比如就把上面的Emp_addEmp等放到這個(gè)Hashmap中。然后把Hashmap保存在一個(gè)UserInfoBean中。最后把這個(gè)UserInfoBean放到Session中,這樣在整個(gè)程序的運(yùn)行過程中,系統(tǒng)隨時(shí)都可以取得這個(gè)用戶的身份信息。 ?
? 三.根據(jù)用戶的權(quán)限做出不同的顯示。 ?
? 可以對(duì)比當(dāng)前員工的權(quán)限和給這個(gè)菜單分配的“功能ID”判斷當(dāng)前用戶是否有打開這個(gè)菜單的權(quán)限。例如:如果保存員工權(quán)限的Hashmap中沒有這三個(gè)ID的任何一個(gè),那這個(gè)菜單就不會(huì)顯示,如果員工的Hashmap中有任何一個(gè)ID,那這個(gè)菜單都會(huì)顯示。 ? ?
? 對(duì)于一個(gè)新聞系統(tǒng)(Resouce),假設(shè)它有這樣的功能(Privilege):查看,發(fā)布,刪除,修改;假設(shè)對(duì)于刪除,有"新聞系統(tǒng)管理者只能刪除一月前發(fā)布的,而超級(jí)管理員可刪除所有的這樣的限制,這屬于業(yè)務(wù)邏輯(Business ? logic),而不屬于用戶權(quán)限范圍。也就是說權(quán)限負(fù)責(zé)有沒有刪除的Permission,至于能刪除哪些內(nèi)容應(yīng)該根據(jù)UserRole ? or ? UserGroup來決定(當(dāng)然給UserRole ? or ? UserGroup分配權(quán)限時(shí)就應(yīng)該包含上面兩條業(yè)務(wù)邏輯)。 ?
? 一個(gè)用戶可以擁有多種角色,但同一時(shí)刻用戶只能用一種角色進(jìn)入系統(tǒng)。角色的劃分方法可以根據(jù)實(shí)際情況劃分,按部門或機(jī)構(gòu)進(jìn)行劃分的,至于角色擁有多少權(quán)限,這就看系統(tǒng)管理員賦給他多少的權(quán)限了。用戶—角色—權(quán)限的關(guān)鍵是角色。用戶登錄時(shí)是以用戶和角色兩種屬性進(jìn)行登錄的(因?yàn)橐粋€(gè)用戶可以擁有多種角色,但同一時(shí)刻只能扮演一種角色),根據(jù)角色得到用戶的權(quán)限,登錄后進(jìn)行初始化。這其中的技巧是同一時(shí)刻某一用戶只能用一種角色進(jìn)行登錄。 ?
? 針對(duì)不同的“角色”動(dòng)態(tài)的建立不同的組,每個(gè)項(xiàng)目建立一個(gè)單獨(dú)的Group,對(duì)于新的項(xiàng)目,建立新的 ? Group ? 即可。在權(quán)限判斷部分,應(yīng)在商業(yè)方法上予以控制。比如:不同用戶的“操作能力”是不同的(粗粒度的控制應(yīng)能滿足要求),不同用戶的“可視區(qū)域”是不同的(體現(xiàn)在對(duì)被操作的對(duì)象的權(quán)限數(shù)據(jù),是否允許當(dāng)前用戶訪問,這需要對(duì)業(yè)務(wù)數(shù)據(jù)建模的時(shí)候考慮權(quán)限控制需要)。???
?
擴(kuò)展性: ?
? 有了用戶/權(quán)限管理的基本框架,Who(User/Group)的概念是不會(huì)經(jīng)常需要擴(kuò)展的。變化的可能是系統(tǒng)中引入新的 ? What ? (新的Resource類型)或者新的How(新的操作方式)。那在三個(gè)基本概念中,僅在Permission上進(jìn)行擴(kuò)展是不夠的。這樣的設(shè)計(jì)中Permission實(shí)質(zhì)上解決了How ? 的問題,即表示了“怎樣”的操作。那么這個(gè)“怎樣”是在哪一個(gè)層次上的定義呢?將Permission定義在“商業(yè)方法”級(jí)別比較合適。比如,發(fā)布、購(gòu)買、取消。每一個(gè)商業(yè)方法可以意味著用戶進(jìn)行的一個(gè)“動(dòng)作”。定義在商業(yè)邏輯的層次上,一方面保證了數(shù)據(jù)訪問代碼的“純潔性”,另一方面在功能上也是“足夠”的。也就是說,對(duì)更低層次,能自由的訪問數(shù)據(jù),對(duì)更高層次,也能比較精細(xì)的控制權(quán)限。 ?
? 確定了Permission定義的合適層次,更進(jìn)一步,能夠發(fā)現(xiàn)Permission實(shí)際上還隱含了What的概念。也就是說,對(duì)于What的How操作才會(huì)是一個(gè)完整的Operator。比如,“發(fā)布”操作,隱含了“信息”的“發(fā)布”概念,而對(duì)于“商品”而言發(fā)布操作是沒有意義的。同樣的,“購(gòu)買”操作,隱含了“商品”的“購(gòu)買”概念。這里的綁定還體現(xiàn)在大量通用的同名的操作上,比如,需要區(qū)分“商品的刪除”與“信息的刪除”這兩個(gè)同名為“刪除”的不同操作。 ?
? 提供權(quán)限系統(tǒng)的擴(kuò)展能力是在Operator ? (Resource ? + ? Permission)的概念上進(jìn)行擴(kuò)展。Proxy ? 模式是一個(gè)非常合適的實(shí)現(xiàn)方式。實(shí)現(xiàn)大致如下:在業(yè)務(wù)邏輯層(EJB ? Session ? Facade ? [Stateful ? SessionBean]中),取得該商業(yè)方法的Methodname,再根據(jù)Classname和 ? Methodname ? 檢索Operator ? 數(shù)據(jù),然后依據(jù)這個(gè)Operator信息和Stateful中保存的User信息判斷當(dāng)前用戶是否具備該方法的操作權(quán)限。 ?
? 應(yīng)用在 ? EJB ? 模式下,可以定義一個(gè)很明確的 ? Business層次,而一個(gè)Business ? 可能意味著不同的視圖,當(dāng)多個(gè)視圖都對(duì)應(yīng)于一個(gè)業(yè)務(wù)邏輯的時(shí)候,比如,Swing ? Client以及 ? Jsp ? Client ? 訪問的是同一個(gè) ? EJB ? 實(shí)現(xiàn)的 ? Business。在 ? Business ? 層上應(yīng)用權(quán)限較能提供集中的控制能力。實(shí)際上,如果權(quán)限系統(tǒng)提供了查詢能力,那么會(huì)發(fā)現(xiàn),在視圖層次已經(jīng)可以不去理解權(quán)限,它只需要根據(jù)查詢結(jié)果控制界面就可以了。 ?
? 靈活性: ?
? Group和Role,只是一種輔助實(shí)現(xiàn)的手段,不是必需的。如果系統(tǒng)的Role很多,逐個(gè)授權(quán)違背了“簡(jiǎn)單,方便”的目的,那就引入Group,將權(quán)限相同的Role組成一個(gè)Group進(jìn)行集中授權(quán)。Role也一樣,是某一類Operator的集合,是為了簡(jiǎn)化針對(duì)多個(gè)Operator的操作。 ?
? Role把具體的用戶和組從權(quán)限中解放出來。一個(gè)用戶可以承擔(dān)不同的角色,從而實(shí)現(xiàn)授權(quán)的靈活性。當(dāng)然,Group也可以實(shí)現(xiàn)類似的功能。但實(shí)際業(yè)務(wù)中,Group劃分多以行政組織結(jié)構(gòu)或業(yè)務(wù)功能劃分;如果為了權(quán)限管理強(qiáng)行將一個(gè)用戶加入不同的組,會(huì)導(dǎo)致管理的復(fù)雜性。 ?
? Domain的應(yīng)用。為了授權(quán)更靈活,可以將Where或者Scope抽象出來,稱之為Domain,真正的授權(quán)是在Domain的范圍內(nèi)進(jìn)行,具體的Resource將分屬于不同的Domain。比如:一個(gè)新聞機(jī)構(gòu)有國(guó)內(nèi)與國(guó)外兩大分支,兩大分支內(nèi)又都有不同的資源(體育類、生活類、時(shí)事政治類)。假如所有國(guó)內(nèi)新聞的權(quán)限規(guī)則都是一樣的,所有國(guó)外新聞的權(quán)限規(guī)則也相同。則可以建立兩個(gè)域,分別授權(quán),然后只要將各類新聞與不同的域關(guān)聯(lián),受域上的權(quán)限控制,從而使之簡(jiǎn)化。 ?
? 權(quán)限系統(tǒng)還應(yīng)該考慮將功能性的授權(quán)與資源性的授權(quán)分開。很多系統(tǒng)都只有對(duì)系統(tǒng)中的數(shù)據(jù)(資源)的維護(hù)有權(quán)限控制,但沒有對(duì)系統(tǒng)功能的權(quán)限控制。 ?
? 權(quán)限系統(tǒng)最好是可以分層管理而不是集中管理。大多客戶希望不同的部門能且僅能管理其部門內(nèi)部的事務(wù),而不是什么都需要一個(gè)集中的Administrator或Administrators組來管理。雖然你可以將不同部門的人都加入Administrators組,但他們的權(quán)限過大,可以管理整個(gè)系統(tǒng)資源而不是該部門資源。 ?
? 正向授權(quán)與負(fù)向授權(quán):正向授權(quán)在開始時(shí)假定主體沒有任何權(quán)限,然后根據(jù)需要授予權(quán)限,適合于權(quán)限要求嚴(yán)格的系統(tǒng)。負(fù)向授權(quán)在開始時(shí)假定主體有所有權(quán)限,然后將某些特殊權(quán)限收回。 ?
? 權(quán)限計(jì)算策略:系統(tǒng)中User,Group,Role都可以授權(quán),權(quán)限可以有正負(fù)向之分,在計(jì)算用戶的凈權(quán)限時(shí)定義一套策略。 ?
? 系統(tǒng)中應(yīng)該有一個(gè)集中管理權(quán)限的AccessService,負(fù)責(zé)權(quán)限的維護(hù)(業(yè)務(wù)管理員、安全管理模塊)與使用(最終用戶、各功能模塊),該AccessService在實(shí)現(xiàn)時(shí)要同時(shí)考慮一般權(quán)限與特殊權(quán)限。雖然在具體實(shí)現(xiàn)上可以有很多,比如用Proxy模式,但應(yīng)該使這些Proxy依賴于AccessService。各模塊功能中調(diào)用AccessService來檢查是否有相應(yīng)的權(quán)限。所以說,權(quán)限管理不是安全管理模塊自己一個(gè)人的事情,而是與系統(tǒng)各功能模塊都有關(guān)系。每個(gè)功能模塊的開發(fā)人員都應(yīng)該熟悉安全管理模塊,當(dāng)然,也要從業(yè)務(wù)上熟悉本模塊的安全規(guī)則。 ?
? 技術(shù)實(shí)現(xiàn): ?
? 1.表單式認(rèn)證,這是常用的,但用戶到達(dá)一個(gè)不被授權(quán)訪問的資源時(shí),Web容器就發(fā) ?
? 出一個(gè)html頁(yè)面,要求輸入用戶名和密碼。 ? ?
? 2.一個(gè)基于Servlet ? Sign ? in/Sign ? out來集中處理所有的Request,缺點(diǎn)是必須由應(yīng)用程序自己來處理。 ?
? 3.用Filter防止用戶訪問一些未被授權(quán)的資源,F(xiàn)ilter會(huì)截取所有Request/Response, ?
? 然后放置一個(gè)驗(yàn)證通過的標(biāo)識(shí)在用戶的Session中,然后Filter每次依靠這個(gè)標(biāo)識(shí)來決定是否放行Response。 ?
? 這個(gè)模式分為: ?
? Gatekeeper ? :采取Filter或統(tǒng)一Servlet的方式。 ?
? Authenticator: ? 在Web中使用JAAS自己來實(shí)現(xiàn)。 ?
? 用戶資格存儲(chǔ)LDAP或數(shù)據(jù)庫(kù): ?
? 1. ? Gatekeeper攔截檢查每個(gè)到達(dá)受保護(hù)的資源。首先檢查這個(gè)用戶是否有已經(jīng)創(chuàng)建 ?
? 好的Login ? Session,如果沒有,Gatekeeper ? 檢查是否有一個(gè)全局的和Authenticator相關(guān)的session? ?
? 2. ? 如果沒有全局的session,這個(gè)用戶被導(dǎo)向到Authenticator的Sign-on ? 頁(yè)面, ?
? 要求提供用戶名和密碼。 ?
? 3. ? Authenticator接受用戶名和密碼,通過用戶的資格系統(tǒng)驗(yàn)證用戶。 ?
? 4. ? 如果驗(yàn)證成功,Authenticator將創(chuàng)建一個(gè)全局Login ? session,并且導(dǎo)向Gatekeeper ?
? 來為這個(gè)用戶在他的web應(yīng)用中創(chuàng)建一個(gè)Login ? Session。 ?
? 5. ? Authenticator和Gatekeepers聯(lián)合分享Cookie,或者使用Tokens在Query字符里。
但凡涉及多用戶不同權(quán)限的網(wǎng)絡(luò)或者單機(jī)程序,都會(huì)有權(quán)限管理的問題,比較突出的是MIS系統(tǒng)。 ? ?
? ?
? 下面我要說的是MIS系統(tǒng)權(quán)限管理的數(shù)據(jù)庫(kù)設(shè)計(jì)及實(shí)現(xiàn),當(dāng)然,這些思路也可以推廣開來應(yīng)用,比如說在BBS中用來管理不同級(jí)別的用戶權(quán)限。 ? ?
? ?
? 權(quán)限設(shè)計(jì)通常包括數(shù)據(jù)庫(kù)設(shè)計(jì)、應(yīng)用程序接口(API)設(shè)計(jì)、程序?qū)崿F(xiàn)三個(gè)部分。 ? ?
? ?
? 這三個(gè)部分相互依存,密不可分,要實(shí)現(xiàn)完善的權(quán)限管理體系,必須考慮到每一個(gè)環(huán)節(jié)可行性與復(fù)雜程度甚至執(zhí)行效率。 ? ?
? ?
? 我們將權(quán)限分類,首先是針對(duì)數(shù)據(jù)存取的權(quán)限,通常有錄入、瀏覽、修改、刪除四種,其次是功能,它可以包括例如統(tǒng)計(jì)等所有非直接數(shù)據(jù)存取操作,另外,我們還可能對(duì)一些關(guān)鍵數(shù)據(jù)表某些字段的存取進(jìn)行限制。除此,我想不出還有另外種類的權(quán)限類別。 ? ?
? ?
? 完善的權(quán)限設(shè)計(jì)應(yīng)該具有充分的可擴(kuò)展性,也就是說,系統(tǒng)增加了新的其它功能不應(yīng)該對(duì)整個(gè)權(quán)限管理體系帶來較大的變化,要達(dá)到這個(gè)目的,首先是數(shù)據(jù)庫(kù)設(shè)計(jì)合理,其次是應(yīng)用程序接口規(guī)范。 ? ?
? ?
? 我們先討論數(shù)據(jù)庫(kù)設(shè)計(jì)。通常我們使用關(guān)系數(shù)據(jù)庫(kù),這里不討論基于Lotus產(chǎn)品的權(quán)限管理。 ? ?
? ?
? 權(quán)限表及相關(guān)內(nèi)容大體可以用六個(gè)表來描述,如下: ? ?
? 1 ? 角色(即用戶組)表:包括三個(gè)字段,ID,角色名,對(duì)該角色的描述; ? ?
? 2 ? 用戶表:包括三個(gè)或以上字段,ID,用戶名,對(duì)該用戶的描述,其它(如地址、電話等信息); ? ?
? 3 ? 角色-用戶對(duì)應(yīng)表:該表記錄用戶與角色之間的對(duì)應(yīng)關(guān)系,一個(gè)用戶可以隸屬于多個(gè)角色,一個(gè)角色組也可擁有多個(gè)用戶。包括三個(gè)字段,ID,角色I(xiàn)D,用戶ID; ? ?
? 4 ? 限制內(nèi)容列表:該表記錄所有需要加以權(quán)限區(qū)分限制的數(shù)據(jù)表、功能和字段等內(nèi)容及其描述,包括三個(gè)字段,ID,名稱,描述; ? ?
? 5 ? 權(quán)限列表:該表記錄所有要加以控制的權(quán)限,如錄入、修改、刪除、執(zhí)行等,也包括三個(gè)字段,ID,名稱,描述; ? ?
? 6 ? 權(quán)限-角色-用戶對(duì)應(yīng)表:一般情況下,我們對(duì)角色/用戶所擁有的權(quán)限做如下規(guī)定,角色擁有明令允許的權(quán)限,其它一律禁止,用戶繼承所屬角色的全部權(quán)限,在此范圍內(nèi)的權(quán)限除明令禁止外全部允許,范圍外權(quán)限除明令允許外全部禁止。該表的設(shè)計(jì)是權(quán)限管理的重點(diǎn),設(shè)計(jì)的思路也很多,可以說各有千秋,不能生搬硬套說某種方法好。對(duì)此,我的看法是就個(gè)人情況,找自己覺得合適能解決問題的用。 ? ?
? ?
? 先說第一種也是最容易理解的方法,設(shè)計(jì)五個(gè)字段:ID,限制內(nèi)容ID,權(quán)限ID,角色/用戶類型(布爾型字段,用來描述一條記錄記錄的是角色權(quán)限還是用戶權(quán)限),角色/用戶ID,權(quán)限類型(布爾型字段,用來描述一條記錄表示允許還是禁止) ? ?
? ?
? 好了,有這六個(gè)表,根據(jù)表六,我們就可以知道某個(gè)角色/用戶到底擁有/禁止某種權(quán)限。 ? ?
? ?
? 或者說,這么設(shè)計(jì)已經(jīng)足夠了,我們完全實(shí)現(xiàn)了所需要的功能:可以對(duì)角色和用戶分別進(jìn)行權(quán)限定制,也具有相當(dāng)?shù)目蓴U(kuò)展性,比如說增加了新功能,我們只需要添加一條或者幾條記錄就可以,同時(shí)應(yīng)用程序接口也無須改動(dòng),具有相當(dāng)?shù)目尚行浴5牵诔绦驅(qū)崿F(xiàn)的過程中,我們發(fā)現(xiàn),使用這種方法并不是十分科學(xué),例如瀏覽某個(gè)用戶所擁有的權(quán)限時(shí),需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行多次(甚至是遞歸)查詢,極不方便。于是我們需要想其它的辦法。使用過Unix系統(tǒng)的人們都知道,Unix文件系統(tǒng)將對(duì)文件的操作權(quán)限分為三種:讀、寫和執(zhí)行,分別用1、2、4三個(gè)代碼標(biāo)識(shí),對(duì)用戶同時(shí)具有讀寫權(quán)限的文件被記錄為3,即1+2。我們也可以用類似的辦法來解決這個(gè)問題。初步的想法是修改權(quán)限列表,加入一個(gè)字段:標(biāo)識(shí)碼,例如,我們可以將錄入權(quán)限標(biāo)識(shí)為1,瀏覽權(quán)限標(biāo)識(shí)為2,修改權(quán)限標(biāo)識(shí)為4,刪除權(quán)限標(biāo)識(shí)為8,執(zhí)行權(quán)限標(biāo)識(shí)為16,這樣,我們通過權(quán)限累加的辦法就可以輕易的將原本要分為幾條記錄描述的權(quán)限放在一起了,例如,假定某用戶ID為1,庫(kù)存表對(duì)應(yīng)的限制內(nèi)容ID為2,同時(shí)規(guī)定角色類型為0、用戶類型為1,我們就可以將該用戶具有錄入、瀏覽、修改、刪除庫(kù)存表的權(quán)限描述為:2,15,1,1。 ? ?
? ?
? 確實(shí)很簡(jiǎn)單,不是嗎?甚至還有更過激的辦法,將限制內(nèi)容列表也加上一列,定義好標(biāo)識(shí)碼,這樣,我們甚至可以用簡(jiǎn)單的一條記錄描述某個(gè)用戶具有的對(duì)全部?jī)?nèi)容所具有的全部權(quán)限了。當(dāng)然,這樣做的前提是限制內(nèi)容數(shù)量比較小,不然,呵呵,2的n次方遞增起來可是數(shù)量驚人,不容易解析的。 ? ?
? ?
? 從表面上看,上述方法足以達(dá)到實(shí)現(xiàn)功能、簡(jiǎn)化數(shù)據(jù)庫(kù)設(shè)計(jì)及實(shí)現(xiàn)的復(fù)雜度這個(gè)目的,但這樣做有個(gè)弊端,我們所涉及的權(quán)限列表不是相互獨(dú)立而是互相依賴的,比如說修改權(quán)限,其實(shí)是包含瀏覽權(quán)限的,例如,我們可能只是簡(jiǎn)單的設(shè)置用戶對(duì)庫(kù)存表存取的權(quán)限值為錄入+修改+刪除(1+4+8=13),但事實(shí)上,該用戶具有(1+2+4+8=15)的權(quán)限,也就是說,在這種方案中,13=15。于是當(dāng)我們調(diào)用API詢問某用戶是否具有瀏覽權(quán)限時(shí),就必須判斷該用戶是否具有對(duì)該數(shù)據(jù)表的修改權(quán)限,因此,如果不能在程序中固化權(quán)限之間的包含關(guān)系,就不能利用應(yīng)用程序接口簡(jiǎn)單的做出判斷。但這與我們的目的“充分的可擴(kuò)展性”矛盾。 ? ?
? ?
? 這個(gè)問題如何解決?我想到了另外一種設(shè)置標(biāo)識(shí)碼的方法,那就是利用素?cái)?shù)。我們不妨將錄入、瀏覽、修改、刪除、執(zhí)行的基本標(biāo)志碼定為2,3,5,7,11,當(dāng)遇到權(quán)限互相包含的時(shí)候,我們將它的標(biāo)識(shí)碼設(shè)定為兩個(gè)(或多個(gè))基本標(biāo)志碼的乘積,例如,可以將“修改”功能的標(biāo)志碼定為3*5=15,然后將所有的權(quán)限相乘,就得到了我們需要的最終權(quán)限標(biāo)識(shí)值。這樣,我們?cè)谠儐栍脩羰欠窬哂心稠?xiàng)權(quán)限的時(shí)候,只需要將最終的值分解成質(zhì)因子,例如,我們可以定義一個(gè)用戶具有錄入+修改+刪除庫(kù)存表的權(quán)限為 ? 2*15*7=2*3*5*7,即表示,該用戶具有了對(duì)庫(kù)存表錄入+瀏覽+修改+刪除權(quán)限。 ? ?
? ?
? 當(dāng)然,對(duì)權(quán)限列表我們使用上述方法的前提是權(quán)限列表記錄條數(shù)不會(huì)太多并且關(guān)系不是十分復(fù)雜,否則,光是解析權(quán)限代碼就要機(jī)器忽悠半宿:) ? ?
? ?
? 我希望以上的分析是正確且有效的(事實(shí)上,我也用這些的方法在不止一套系統(tǒng)中實(shí)現(xiàn)),但無論如何,我覺得如此實(shí)現(xiàn)權(quán)限管理,只是考慮了數(shù)據(jù)庫(kù)設(shè)計(jì)和應(yīng)用程序接口兩部分內(nèi)容,對(duì)于實(shí)現(xiàn),還是顯得很費(fèi)勁。因此,我懇請(qǐng)有過類似設(shè)計(jì)、實(shí)現(xiàn)經(jīng)驗(yàn)的同志們提出建設(shè)性的意見和修改建議。 ? ?
? ?
? 另外,關(guān)于數(shù)據(jù)庫(kù)設(shè)計(jì)的思路還有使用二維表的,這將在以后的時(shí)間里討論,關(guān)于應(yīng)用程序接口的設(shè)計(jì)和實(shí)現(xiàn)我也將在利用另外篇幅和大家共同探討,代碼將用類C語(yǔ)法實(shí)現(xiàn)(我不喜歡pascal,抱歉)?????
????
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
