許可權管理系統(四)
阿新 • • 發佈:2019-02-02
背景
多數企業應用都需要對資料許可權進行控制,如:某個使用者只能看到某個範圍的資料(資料行)、某個使用者只能看到某幾列資料(資料列)。本文以資料行級別的許可權控制為範例,談談如何設計許可權模型和查詢 API。
許可權模型
結合自己的專案需求,可以省略掉“資料角色”,直接讓“使用者”聚合“資料許可權”,也可以只保留一個“角色”,讓“角色”聚合“操作許可權”和“資料許可權”。
可擴充套件的資料許可權模型
虛擬碼示例
1 class SessionInfo 2 { 3 public Guid UserId { get; set; } 4 5public Guid DepartmentId { get; set; } 6 } 7 8 interface IDataPermissionProvider 9 { 10 string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args); 11 } 12 13 [DisplayName("我的")] 14 class DepartmentDataPermissionProvider : IDataPermissionProvider15 { 16 public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args) 17 { 18 return String.Format("( CreateUserId = '{0}' )", sessionInfo.UserId); 19 } 20 } 21 22 [DisplayName("指定部門")] 23 class MySelfDataPermissionProvider : IDataPermissionProvider24 { 25 public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args) 26 { 27 return String.Format("( DepartmentId = '{0}' )", args["DepartmentId"]); 28 } 29 }
草圖示例
說明
很容易將這部分“外掛化”,如支援“自定義”,然後顯示一個輸入框,可以輸入:“Price > 130”。
如何設計查詢API?
先看兩個用例
上面兩個用例,對訂單有兩種查詢需求,我們如何設計這種查詢 API 呢?
- 第一種:
1 class QueryService 2 { 3 public QueryResult Query(UserCase userCase, DynamicQuery query) 4 { 5 // 根據 userCase 決定是否或如何動態的追加資料許可權。 6 return null; 7 } 8 }
需要根據不同的 UserCase,決定是否追加資料許可權,如:A 用例需要資料許可權,B 用例不需要,UserCase 可能是“當前請求的模組名字”或“當前請求的URL”。
- 第二種:
class QueryService { public QueryResult QueryA(DynamicQuery query) { return null; } public QueryResult QueryB(DynamicQuery query) { return null; } }
我更喜歡這種風格。
上面的 DynamicQuery 並不是“萬能的查詢條件”,而是滿足某一用例的不同查詢組合的一種“規約”,很多系統都提供“萬能查詢”,也算是一種特殊的“規約”了。
另外需要注意的是:一個用例會有多種查詢需求的(或者叫查詢組合)。