Posted on 2005-11-26 10:46
canonical 閱讀(655)
評論(0) 編輯 收藏 所屬分類:
設計理論
權限控制中,subject可能不會簡單的對應于userId, 而是包含一系列的security token或certificate,
例如用戶登陸地址,登陸時間等。一般情況下,這些信息在權限系統中的使用都是很直接的,不會造成什么問題。
subject域中最重要的結構是user和role的分離,可以在不存在user的情況下,為role指定權限。有人進一步定義了userGroup的
概念,可以為userGroup指定role,而user從其所屬的group繼承role的設置。一般情況下,我不提倡在權限系統中引入
userGroup的概念。這其中最重要的原因就是它會造成多條權限信息傳遞途徑,從而產生一種路徑依賴,
并可能出現信息沖突的情況。一般user與group的關聯具有明確的業務含義,因而不能隨意取消。如果我們希望對user擁有的權限進行細調,除去
user從group繼承的某個不應該擁有的權限,解決的方法很有可能是所謂的負權限,即某個權限條目描述的是不能做某某事。負權限會造成各個權限設置之
間的互相影響,造成必須嘗試所有權限規則才能作出判斷的困境,引出對額外的消歧策略的需求,這些都極大的限制了系統的可擴展性。在允許負權限的環境中,管
理員將無法直接斷定某個權限設置的最終影響,他必須在頭腦中完成所有的權限運算之后才能理解某用戶最終擁有的實際權限,如果發現權限設置沖突,管理員可能
需要多次嘗試才能找到合適方案。這種配置時的推理需求可能會增加配置管理的難度,造成微妙的安全漏洞,而且負權限導致的全局關聯也降低了權限系統的穩定
性。我更傾向于將group作為權限設置時的一種輔助標記手段,系統中只記錄用戶最終擁有的角色,即相當于記錄用戶通過group擁有權限的推導完成的結
果,
如果需要權限細調,我們直接在用戶擁有的角色列表上直接進行。當然,如果實現的復雜一些,權限系統對外暴露的接口仍然可以模擬為能夠指定
userGroup的權限。
推理在面向對象語言中最明顯的表現是繼承,所以有些人將subject域中的推理直接等價于role之間的繼承問題,這未必是最好的選擇。繼承可以形成非
常復雜的推理關系,但是可能過于復雜了(特別是直接使用sql語句無法實現樹形推理查詢)。按照級列理論,從不相關發展到下一階段是出現簡單的序關系,即
我們可以說subject出現級別上的差異,高級別subject將自動具有低級別的權限。一種選擇是定義roleRank,規定高級別role自動具有
低級別role的權限,但考慮到user與role的兩分結構,我們也可以同時定義userRank和roleRank,規定高級別user自動具有低級
別的role,而role之間不具有推理關系。在面向對象領域中,我們已經證實了完全采用繼承來組織對象關系會導致系統的不穩定,所以我傾向于第二種選
擇,即將role看作某種類似于interface的東西,一種權限的切片。為了進一步限制這種推導關系,我們可以定義所謂的安全域的概念.
security domain, 規定推導只能在一定的域中才能進行。
select user.userId, role.roleId
from user, role
where user.userRank > role.roleRank
and user.domain = role.domain
將權限控制一般需要施加在最細的粒度上,這在復雜的系統中可能過于理想化了。復雜的情況下我們需要進行局部化設計,即進行某些敏感操作之前進行一系列復雜
的權限校驗工作。當完成這些工作之后,進入某個security zone, 在其中進行操作就不再需要校驗了。
總的來說,權限系統采用非常復雜的結構效果未必理想。很多時候只是個管理模式的問題,應該盡量通過重新設計權限空間的結構來加以規避。不過在一些非常復雜
的權限控制環境下,也許簡單的描述信息確實很難有效的表達權限策略(雖然我從未遇到過),此時嘗試一下規則引擎可能比在權限系統中強行塞入越來越多的約束
要好的多。