許可權系統設計(3)-- subject

lastwinner發表於2008-04-10
許可權控制中,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, 在其中進行操作就不再需要校驗了。

總的來說,許可權系統採用非常複雜的結構效果未必理想。很多時候只是個管理模式的問題,應該儘量透過重新設計許可權空間的結構來加以規避。不過在一些非常複雜的許可權控制環境下,也許簡單的描述資訊確實很難有效的表達許可權策略(雖然我從未遇到過),此時嘗試一下規則引擎可能比在許可權系統中強行塞入越來越多的約束要好的多

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29867/viewspace-232369/,如需轉載,請註明出處,否則將追究法律責任。

相關文章