iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0

前言

昨天談到 RBAC 用 Role 當作 User 與 Permission 之間的中間層,能有效降低管理成本,但也提到一個限制:如果規則牽涉大量動態條件(例如「只能在上班時間存取」「只能存取自己部門的資源」),RBAC 就容易出現 Role Explosion——角色數量隨著條件組合不斷增加,最後比逐一設定 Permission 更難維護。

今天要介紹的 ABAC(Attribute-Based Access Control,屬性型存取控制),就是為了解決這類問題而設計的模型。ABAC 不再只看「你是什麼角色」,而是同時檢查 Subject、Resource 與 Environment 的各種屬性,再依照政策動態計算出 Allow 或 Deny。

今天內容涵蓋:

  1. ABAC 如何根據屬性做出授權決定
  2. ABAC vs RBAC
  3. Token 如何提供 ABAC 所需的屬性
  4. 導入 ABAC 前要考慮的事
  5. 小結

一、ABAC 如何根據屬性做出授權決定

ABAC(Attribute-Based Access Control,屬性型存取控制)不只看 User 擁有什麼 Role,而是根據請求當下的屬性,動態決定 Allow 或 Deny。一次 ABAC 判斷可以理解為:某個 Subject 想對 Resource 執行 Action,系統再依照 Environment 與 Policy 檢查相關屬性。

判斷資訊 說明 常見屬性範例
Subject 提出請求的人或服務 部門、職等、Role、Clearance Level
Resource 要存取的物件 擁有者、機密等級、資料分類
Action 要執行的操作 Read、Write、Delete
Environment 請求發生時的情境 時間、地點、裝置類型

將表格中的資訊組合起來,就能形成一條完整的 ABAC Policy。例如:Gloria 所屬的部門是 HR、要讀取的資料標記為 internal,而且請求發生在下午六點以前時,允許 Gloria 執行 Read。

系統收到請求後,會依序確認 Gloria 的部門、資料的機密等級、這次執行的 Action,以及請求發生的時間。所有條件都成立時,結果才是 Allow;只要其中一項不符合,這條 Policy 就不會允許存取。若沒有其他 Policy 明確允許,系統便採用預設 Deny。

同一個請求可能同時符合多條 Policy,因此實作時還要先定義衝突處理方式,例如 Deny 優先。這樣才能避免一條 Policy 允許、另一條 Policy 拒絕時,系統產生不一致的判斷。

💡XACML(eXtensible Access Control Markup Language)是描述 ABAC Policy 的標準之一;不同平台通常會使用各自的 Policy 語法表達這類規則。


二、ABAC vs RBAC

比較項目 RBAC ABAC
存取控制依據 Role 屬性(User/Resource/Environment)
精細度 較粗(以角色為單位) 較細(以屬性組合為單位)
彈性 有限 高,可即時反映情境變化
複雜度 較簡單 較複雜,政策數量可能快速增加
管理方式 管理 Role 與指派 管理 Policy 與屬性來源
適合情境 權限結構穩定、職務清楚 需要動態、依情境調整的存取控制

兩者不是互斥的選擇。實務上常先用 RBAC 建立基本權限,再用 ABAC 補上少數需要動態判斷的條件。這樣既能保留 Role 容易管理的優點,也能處理時間、部門或資源標籤等情境。


三、Token 如何提供 ABAC 所需的屬性

OAuth 2.0 與 ABAC 處理的是不同階段:OAuth 2.0 讓 Client 取得 Access Token,ABAC 則由 Resource Server 根據屬性與 Policy,判斷這次請求是否可以執行。兩者可以搭配使用,但不能把「持有 Token」直接視為「一定有權限」。

如果 Access Token 採用 JWT 格式,Token 中的 Claim 通常只提供 Subject 相關資訊。Resource Server 還要從其他來源補上 Resource、Action 與 Environment,組成一次完整的授權判斷資料。例如:

{
  "subject": {
    "id": "usr_gloria",
    "department": "HR",
    "clearance": "internal",
    "tenant_id": "shop-a",
    "scope": ["document:read"]
  },
  "resource": {
    "id": "doc_payroll_2026",
    "type": "document",
    "classification": "confidential",
    "tenant_id": "shop-a"
  },
  "action": "read",
  "environment": {
    "time": "2026-09-06T14:00:00+08:00",
    "network": "corporate"
  }
}

這不是 Access Token 原本的完整內容,而是 Resource Server 將不同來源的屬性整理成同一份授權判斷資料。JSON 與來源的對應關係如下:

JSON 欄位 資料來源 本例內容
subject Access Token 的 Claim User ID、部門、權限等級、Tenant、Scope
resource 文件資料或 Resource Metadata 文件 ID、類型、機密等級、Tenant
action API Request read
environment Request Context 請求時間、網路環境

接著,Resource Server 會把這些資料帶入授權判斷流程:

  1. 驗證 Access Token 的簽章、Issuer、Audience 與有效期限。
  2. 從 Token 的 Claim 取得 Gloria 的部門、權限等級與 Scope。
  3. 從資料庫或資源中取得資料分類與擁有者等 Resource 屬性。
  4. 取得這次請求的 Action、時間與位置等 Environment 屬性。
  5. 將所有資訊交給 ABAC Policy,計算結果是 Allow 或 Deny。

因此,即使 Token 顯示 Gloria 屬於 HR,並具有 document:read Scope;只要目標文件的機密等級高於 Gloria 的 Clearance Level,ABAC Policy 仍然可以拒絕請求。

💡Token 只提供屬性,最後仍由 ABAC Policy 決定 Allow 或 Deny。Token 中的 Claim 是簽發當下的資料;例如 Gloria 轉到其他部門後,舊 Token 可能仍寫著 department=HR。敏感權限因此通常會使用較短的 Token 有效期限,或在每次請求時查詢最新資料。


四、導入 ABAC 前要考慮的事

ABAC 彈性高,但會增加政策設計與執行成本。實際導入前,可以先評估以下幾點:

  • 系統複雜度: 屬性與規則數量增加後,政策會變得難以閱讀與測試,需要更嚴謹的政策管理流程。
  • 效能: 每次存取都要即時評估屬性與規則,政策複雜時可能影響效能,通常需要搭配快取或預先計算來緩解。
  • 政策衝突: 多條政策同時存在時,可能出現互相矛盾的結果,需要明確的衝突排解規則(例如「Deny 優先」)與定期審查機制。

⚠️ABAC 不是用來取代 RBAC 的萬用解方。多數團隊會保留 RBAC 處理穩定的職務權限,只在少數需要「依情境動態判斷」的場景,例如多租戶隔離、跨部門資料存取、依時間或裝置限制時,才加入 ABAC 規則。


小結

本篇可以整理成以下幾個重點:

  • ABAC 會同時考慮 Subject、Resource、Action 與 Environment 的屬性,動態決定 Allow 或 Deny,而不是只依賴 Role。
  • Access Token 可以提供 User 身分、部門與 Scope 等資訊,但 Resource Server 仍要補上資源與請求情境,才能交由 ABAC Policy 判斷。
  • ABAC 適合處理時間、部門、機密等級與裝置狀態等動態條件,但也會增加屬性管理、效能與政策衝突的複雜度。
  • 實務上通常以 RBAC 建立基本權限,再由 ABAC 補上少數需要依情境判斷的限制,而不是在兩者之間擇一使用。

下一篇將介紹 ACL(Access Control List)與 ReBAC(Relationship-Based Access Control),比較「直接替資源列出存取名單」與「根據彼此關係授權」這兩種做法。


參考資源


上一篇
Day 21|RBAC:角色型存取控制
系列文
從登入到授權-現代軟體的身分架構指南 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言