1、訪問控制矩陣(ACM)
說明:任意對系統使用者產生價值的用例中的操作均在以下四個維度加以控制:
l Operator(操作者權限控制):
進行某種操作時,操作的主體。分爲:用戶,角色,單位
l OperateMethod(操作方法權限控制):
操作的功能確定,如:讀、寫、查、刪等
l Object(操作對象權限控制):
操作的影響對象,通常是某種業務對象,如:表單
l Object.Fields(操作對象屬性項權限控制)
業務要求對選項敏感的對象屬性項,如:表單的某數據項、表單上的簡單控件等
2、ACM中四維數據的組成
Operator:操作者,根據業務的需要設定控制項目主要分爲用戶、角色、單位三種。根據業務的需要,可以控制Operator的作用先後順序或交併運行規則;
Operate Method:操作方法,根據業務操作的對象的不同,可能是業務操作或是底層的CRUD操作;
Object:操作對象,當前操作的對象,根據業務需求可以是:業務對象,如:項目、表單;
Object Fields:操作對象屬性,要求與權限控制綁定的對象的數據項。如:表單字段、表單控件等。
3、原理簡述
ACM在權限管理和訪問控制時的作用原理。一個ACM是由若干控制系統某項操作行爲的若干要素組成的規則矩陣。設想一個場景,當某項操作進行時,必然有如下元素:操作者、操作方法、操作對象。所有ACM就指定了一次操作必須滿足的各元素的條件。如:有ACM如下:“李厚強”、“修改”、“用戶信息”。就代表:“李厚強可以修改用戶信息”。當然這是一個簡單的例子,事實上,情況遠比這個例子複雜。首先要解決的就是操作對象的實例定位問題。即當如下訪問控制出現時:“李厚強可以修改用戶信息中的姓名,但不能修改用戶信息中的身份證號”。很明顯,現有的三維ACM已經不能滿足要求了。
ACM中的操作對象之所有成爲對象,是因爲其具有以下兩種特徵:一是對象是數據的封裝、二是對象本身包含對現實對象的抽象。數據的封裝簡化了數據處理,抽象使得對象的形式更統一、方法數量可控制。但是,當業務要求權限控制到對象的成員這一級別時,這樣的封裝和抽象無疑將屏蔽掉對象成員的權限敏感性。解決的方法有兩種:
方法1:將對象的有權限敏感的成員也抽象爲ACM中的對象
Operator Operate Method Object
―――――――――――――――――――――――――――――――――
李厚強 修改 用戶信息
李厚強 修改 用戶信息.姓名
李厚強 修改禁止 用戶信息.身份證號
方法2:爲ACM增加第四個維度――Object.Fields,操作對象屬性。
Operator OperateMethod Object Object.Fields
――――――――――――――――――――――――――――――――――――
李厚強 修改 用戶信息 -
李厚強 修改 用戶信息 姓名
李厚強 修改禁止(只能“讀取”) 用戶信息 身份證號
粗看,似乎方法1更具有通用性。但考慮到Object.Fields和Object之間的關係、以及其對OperateMethod的影響,問題並不這麼簡單。原因是,Object是業務對象的抽象,其對應的操作(OperateMethod維度)往往是業務功能操作(BusinessOperate);而Object.Fields所對應的操作往往只有“修改”和“讀取”兩種,或類似的數據操作(DataOperate),其餘的操作控制往往由其所的Object的方法所決定。如:我們不可能獨立於用戶信息去孤立的刪除姓名,而只能“修改”、“讀取”。當我們要刪除某個姓名時,往往是刪除一個用戶。
|
Object |
Object.Fields |
對應操作類別 |
Business Operate |
Data Operate |
備註 |
常見操作均爲功能。如:CRUD 以及於對象相關的業務操作 |
通常只有“修改”和“讀取”控制 |
所有,對於Object和Object.Fields的訪問控制所對應的操作對象和操作方法完全不同,在業務系統中Object和Object.Fields所對應的ACM的被訪問場景也完全不同。在考慮到權限合併、權限干涉等問題,更好的設計應該是將ACM視作四維,或者這樣理解:將系統通用ACM分爲兩個三維的ACM,即雙級ACM。分別控制Object的訪問和Object.Fields的訪問:
Object ACM 和 FieldsACM
4、解決難點
4.1權限合併
雙ACM可以很好的控制權限合併。訪問Object時通過ObjectACM,訪問Object.Fields時,將ObjectACM和FieldsACM進行合併操作,得到最終的訪問控制。
4.2權限干涉
通過ObjectACM與FieldsACM的主從關係來控制權限干涉。ObjectACM爲主ACM,當ACM禁止某操作時就不用在訪問FieldsACM了。(當考慮Operator、OperateMethod後權限干涉情況更加複雜,將在下面加以討論)
4.3維度管理
ACM實現的前提是各維度各自的統一管理。如:操作者應該可以統一管理,當ACM確定Operator元素後,可以準確的根據Operator元素確定起對應的用戶、單位、角色。操作者的統一管理很直接,業務系統多有單位組織管理和用戶管理系統。而操作方法和操作對象的統一管理在一般的業務系統中沒有。爲實現精確的訪問控制,必須將所有的操作對象和操作方法項進行統一的管理。
5、模型測試
測試四維權限管理模型是適用性。
測試1
說明:業務系統簡單功能權限管理的實現,即:對功能訪問控制。
一個業務系統往往在UI層上表現爲若干有組織的分類的功能訪問入口(通常是一個分級菜單組),要求根據當前系統使用者的權限取得相對應的功能訪問項目入口。這裏,ACM完全勝任:
Operator |
OperateMethod |
Object |
Object.Fields |
User/Depart/Role |
訪問* |
功能A入口(菜單項) |
- |
… |
… |
… |
… |
*:對於功能操作入口本身,只有“訪問”一種方法。
撇開操作者(Operator)這一維度中可能產生的權限干涉問題以外,不會產生任何其他問題。
測試2:
說明:業務系統對其所管理信息(業務對象)的簡單管理時的權限管理的實現,即:對業務對象的訪問控制。
實例1:例如任何業務系統都會出現的用戶管理,用戶本身就是一種業務對象。當一個操作者對系統中“用戶”對象進行操作時,訪問控制模塊將根據其權限對其操作進行“允許”或“禁止”。
Operator |
OperateMethod |
Object |
Object.Fields |
User/Depart/Role |
修改 |
User(“用戶”業務對象) |
- |
User/Depart/Role |
讀取 |
User(“用戶”業務對象) |
- |
… |
… |
… |
… |
實例2:例如一個報表管理系統中的已經定義的“報表”,也是一種典型的業務對象。與常見的業務對象不同,“報表”除了常見的CRUD操作,還會有其對應的“提交”、“入歷史庫”等業務相關操作,即:Business Operate。
Operator |
OperateMethod |
Object |
Object.Fields |
User/Depart/Role |
修改 |
ReportSheet(“報表”業務對象) |
- |
User/Depart/Role |
讀取 |
ReportSheet(“報表”業務對象) |
- |
… |
… |
… |
… |
User/Depart/Role |
提交 |
ReportSheet(“報表”業務對象) |
- |
User/Depart/Role |
入歷史庫 |
ReportSheet(“報表”業務對象) |
- |
… |
… |
… |
… |
*:業務對象的操作多是Business Operate
利用四維ACM,避免了將Object.Fields作爲Object的子對象來處理,從而簡化了處理權限干涉問題時的模型。
測試3:
同樣的報表管理系統中的已經定義的“報表”,每個“報表”是作爲一個“工件”來處理的。這種“報表”類似與MS Office 2003的智能文檔:根據業務需求,“報表”中的每個“數據單元格”或簡單控件都要求權限敏感。
Operator |
OperateMethod |
Object |
Object.Fields |
User/Depart/Role |
修改 |
ReportSheet(“報表”業務對象) |
單元格A |
User/Depart/Role |
讀取 |
ReportSheet(“報表”業務對象) |
單元格B |
… |
… |
… |
… |
User/Depart/Role |
激活 |
ReportSheet(“報表”業務對象) |
按鈕1 |
User/Depart/Role |
激活 |
ReportSheet(“報表”業務對象) |
按鈕2 |
… |
… |
… |
… |
*:Object.Fields對應的操作多是Data Operate:對於單元格、數據項就是“修改”、“讀取”;對於簡單控件就是“可見”、“激活”。
**:此時的Object維被弱化,成爲Object.Fields的索引項
由於對Object的ACM和對Object.Fields的ACM是分開的,便於處理權限干涉問題。如:根據業務需要,UserA具有對ReportSheetA的讀取權限,但是但對ReportSheetA中的FieldsA不可讀。這時利用算法根據ObjectACM和FieldsACM進行合併即可,不必將Field視作Object的成員來進行訪問控制,更不用將Field視作Object的子對象。
6、實踐指導
其實,這裏用於測試的四個場景基本覆蓋了報表系統的訪問控制的情況。下面,以此作爲業務標本,簡要描述如何在具體業務系統中實現ACM的訪問控制。
訪問控制類
最先的思路是在一個業務系統中設立一個通用的ACM。這是自然而然的想法,因爲有很多通用的規則判斷操作、訪問驗證規則等是控制不同對象都需要的,所以利用面向對象的方法,可以將ACM的驗證規則、操作等封裝到對象中,便於業務系統中廣泛複用。
在這裏,將這種對象包含訪問控制操作、驗證規則的類,稱作:訪問控制類AccessController。
圖1:系統中有訪問控制要求的模塊均調用AccessController類
以上模型非常簡單,可操作性好。但很明顯,各個模塊要求的驗證規則雖然具有相同的驗證調用接口,但其驗證規則各不相同。如果要強行將這些規則封裝在同一個類中,並利用參數的變化來控制驗證規則實例的調用,明顯是對抗“組合爆炸”。每增加一個有訪問控制要求的模塊、或每增加一個驗證規則,AccessController都會被增加一組方法,相關的控制參數也有可能有變化,不可避免的會出現“大類”和“長方法”,系統粒度分佈不均勻。
利用接口設計改善。我們不知道一個業務系統中會有若干訪問控制驗證業務規則,分屬於不同的訪問控制模塊,並且隨着系統的升級或需求的變化,有可能會增加新的驗證規則。用接口設計可以一定程度上改善這個問題。
圖2:利用實現類來實現IAccessController接口,
各實現類具有相同的調用格式,不同的規則
改進後的模型可使得開發組在開發時,根據具體訪問控制的要求編寫不同的驗證規則,但同時驗證過程的代碼外形又具有通用性。如圖2演示,每個訪問控制實現類都有IsValidate函數,接受“操作者”、“操作方法”、“操作對象”作爲參數,並驗證該操作的合法性。
提示細節是,IsValidate函數接受的參數也是接口,即:
public bool IsValidate (IOperator, // 操作者接口 IOperateMethod, // 操作方法接口 IAccessObject) // 操作對象接口 |
*:實際設計時可以考慮使用抽象類(Abstract Class)等來替代接口,但原理一致,都是要推遲實現部分,以獲得良好的擴展性。
而爲了配合這樣模型,受權限訪問控制的各要素(“操作者”、“操作方法”、“操作對象”)均需在構架時即接口化。在實現時,根據業務需求實現相應接口,再作爲參數傳入訪問控制驗證函數中。
以上只是初步想法,具體實現形式待定。
7、總結
以上分析僅用作討論。完全的自我消遣,嘿嘿!
附錄A:
對應第5節,模型測試各場景,利用分級的ACM實現業務需求的時序圖,僅供參考:
測試1:
操作流程對象即激發訪問的業務系統組成部分,這裏可以理解爲GUI用戶界面,以及其中的簡單控制。
測試2:
沿用以上時序圖,模仿真實情況:FunctionA即是對某個ReportSheet的訪問。這時FunctionA即是訪問ReportSheetA的操作控制流程對象。
測試3:
對ReportSheetA中的FieldA作訪問,利用FunctionA判斷處理權限干涉問題,交併權限後再訪問ReportSheetA和FieldA。
- end -
Beegee: 和我在一個產品開發中共事了半年的部門經理(其實是產品經理)告訴我可以離開項目組了。半年前,他委託我設計他的產品中的權限管理模塊。於是,我用我貧瘠的大腦給他想了些方案。難得他還那麼看得上,支持我實現了我的設計,當然也加了不少我不喜歡的東西。現在,卻因爲一些原因我要離開這個產品組了,這位經理也不準備對這個模塊再作更多的投入了,於是我想我可以把我的這些的想法拿到我的Blog中了,算是自我消遣吧。^_^,也希望能夠幫助其他程序員完善他們自己的設計,全當反面教材啦!
共兩篇:
1.“ACM四維權限管理模型”(本文)
2.“權限管理與訪問控制概要設計”
其他相關原創: