1. 程式人生 > >許可權管理系統(四)

許可權管理系統(四)

背景

多數企業應用都需要對資料許可權進行控制,如:某個使用者只能看到某個範圍的資料(資料行)、某個使用者只能看到某幾列資料(資料列)。本文以資料行級別的許可權控制為範例,談談如何設計許可權模型和查詢 API。

許可權模型

結合自己的專案需求,可以省略掉“資料角色”,直接讓“使用者”聚合“資料許可權”,也可以只保留一個“角色”,讓“角色”聚合“操作許可權”和“資料許可權”。

可擴充套件的資料許可權模型

虛擬碼示例

複製程式碼
 1     class SessionInfo
 2     {
 3         public Guid UserId { get; set; }
 4 
 5
public 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 : IDataPermissionProvider
15 { 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 : IDataPermissionProvider
24 { 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. 第一種:
    複製程式碼
    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”。

  2. 第二種:
    複製程式碼
        class QueryService
        {
            public QueryResult QueryA(DynamicQuery query)
            {
                return null;
            }
    
            public QueryResult QueryB(DynamicQuery query)
            {
                return null;
            }
        }
    複製程式碼

    我更喜歡這種風格。

上面的 DynamicQuery 並不是“萬能的查詢條件”,而是滿足某一用例的不同查詢組合的一種“規約”,很多系統都提供“萬能查詢”,也算是一種特殊的“規約”了。

另外需要注意的是:一個用例會有多種查詢需求的(或者叫查詢組合)。