首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

.NET 權限控制最佳實踐:Flags Enum 與位運算實現高效授權檢查

     編輯:ASP.NET 基礎

核心概念:位元組合權限模型

將「增、刪、改、查」四種基本權限映射為 2 的冪次,任意組合即為唯一整數。利用位元 AND 運算(&)判斷特定權限是否存在,是經典且高效的授權模式。

標準實作代碼

[Flags]
public enum Permissions {
    None  = 0,
    Add   = 1,  // 2^0 = 0b0001
    Del   = 2,  // 2^1 = 0b0010
    Mod   = 4,  // 2^2 = 0b0100
    Select = 8  // 2^3 = 0b1000
}

// 權限組合範例:擁有「新增」與「修改」= 1 + 4 = 5 (0b0101)
int userPerm = (int)(Permissions.Add | Permissions.Mod); // 值為 5

// 通用權限檢查方法(推薦簡化版)
public static bool HasPermission(int value, Permissions perm) {
    return (value & (int)perm) == (int)perm;
}

// 使用範例
bool canAdd = HasPermission(5, Permissions.Add);    // true  (5 & 1 = 1)
bool canDel = HasPermission(5, Permissions.Del);    // false (5 & 2 = 0)
bool canMod = HasPermission(5, Permissions.Mod);    // true  (5 & 4 = 4)

原版 Switch 寫法解析(教學用)

public static bool IsPermission(int value, Permissions per) {
    bool result = false;
    switch (per) {
        case Permissions.Add:
            result = (value & (int)Permissions.Add) == (int)Permissions.Add; break;
        case Permissions.Del:
            result = (value & (int)Permissions.Del) == (int)Permissions.Del; break;
        case Permissions.Mod:
            result = (value & (int)Permissions.Mod) == (int)Permissions.Mod; break;
        case Permissions.Select:
            result = (value & (int)Permissions.Select) == (int)Permissions.Select; break;
    }
    return result;
}

注意: 原文每個 case 重複轉型,且缺少 default。建議採用上方單行泛型邏輯,編譯器會內聯優化,效能更佳。

資料庫儲存策略

場景欄位類型範例值說明
單一權限集INT / SMALLINT5Add + Mod
多角色權限表RoleId (PK), PermValue (INT)(1, 15), (2, 3)角色 1 擁有全權限 (15),角色 2 僅增刪 (3)
用戶-角色關聯UserId, RoleId...標準 RBAC 中間表

進階擴展:動態權限位分配

當權限項超過 32 個(Int32 上限)或需動態新增權限類別時:

  • 改用 long (Int64) 支援 64 個權限位
  • 或採用 BigInteger (System.Numerics) 理論無上限
  • 企業級建議:權限鍵值表 (EntityId, PermissionKey, Allowed),配合快取,捨棄位運算換取靈活性

常見陷阱與避坑指南

  1. 未標註 [Flags]:雖不影響位運算,但失去 ToString() 顯示「Add, Mod」等友好名稱的功能
  2. 權重非 2 的冪次:如設 Add=1, Del=3 會導致位重疊,檢查邏輯失效
  3. 忽略 None = 0:無權限狀態應顯式定義,避免預設值歧義
  4. 資料庫欄位過小:SQL Server tinyint 只能存 0-255(8 位權限),建議用 smallint 或 int

效能對比

位運算授權檢查:單 CPU 指令周期,納秒級。對比 JOIN 權限表 或 IN 子查詢,吞吐量提升 100-1000 倍,極適合高併發 API 閘道器、中介軟體攔截器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved