認證系統(Authentication)與權限系統(Authorization)解耦設計
您是否曾經與其他開發人員討論過應用程序的權限系統,并很快意識到您也在談論它的認證系統? 這是相當不幸的,但這兩個完全不同的系統經常被合并在一起。
認證服務像護照(證明你是誰),權限服務像簽證(允許你在哪里做什么)
- 護照頒發后不會每天更新(登錄令牌有效期)
- 簽證可動態調整(權限實時刷新)
通過嚴格分離關注點,系統同時獲得 安全性和可維護性 的提升。
在系統設計中一個常見的認知誤區——權限系統(Authorization)和認證系統(Authentication)本質上是兩個獨立的安全邊界,但常因架構耦合被混為一談。
| 維度 | 認證系統(Authentication) | 權限系統(Authorization) |
關鍵問題 |
“你是誰?”(身份驗證) | “你能做什么?”(資源許可) |
| 技術目標 | 證明用戶身份真實性 | 控制資源訪問邊界 |
| 核心組件 | 密碼/OAuth/生物識別 | RBAC/ReBAC/ABAC策略引擎 |
| 輸出結果 | 用戶標識符(如:user_id) |
權限決策(Allow/Deny) |
| 失效場景 | 憑證泄露 → 冒充風險 | 策略錯誤 → 越權操作 |
一、解耦實踐方案
1.1. 架構分層設計
- 認證服務:僅負責生成身份令牌(如JWT中的
sub字段) - 權限服務:獨立微服務,接收
user_id+動作+資源,返回布爾值
1.2. 協議級分離(OAuth 2.0為例)
- 認證階段:獲取
access_token(證明你是合法用戶) - 權限階段:業務服務用
access_token向權限服務發起鑒權請求
// AuthorizationService.cs - 策略驅動的權限檢查
public class AuthorizationService
{
private readonly IRolePermissionRepository _repo; // 注入權限數據源
public bool CheckPermission(int userId, string resource, string action)
{
// 示例:基于角色的權限校驗(RBAC)
var roles = _repo.GetUserRoles(userId);
return _repo.GetPermissions(roles)
.Exists(p => p.Resource == resource && p.Action == action);
}
}
// ABAC(屬性基訪問控制)擴展
public class AttributeAuthorizationService
{
public bool CheckAttributes(int userId, Resource resource, Action action)
{
var userAttributes = _repo.GetUserAttributes(userId);
var policy = _repo.GetPolicyForResource(resource);
// 執行屬性匹配(如:用戶部門=資源所屬部門)
return policy.Evaluate(userAttributes);
}
}
二、最佳實踐參考
標準協議采用
- 認證:OpenID Connect(OIDC)
- 權限:OAuth 2.0 Scope(靜態粗粒度) + https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/(動態細粒度)
基礎設施選擇
- 認證組件:Keycloak/Auth0/Okta
- 權限引擎:Casbin/OPA(Open Policy Agent)/SpiceDB
調試工具鏈
- 權限測試框架:
OPA Rego Playground/ SpiceDB Playground - 登錄流診斷:
oidc-client-js調試器
- 權限測試框架:
歡迎大家掃描下面二維碼成為我的客戶,扶你上云


浙公網安備 33010602011771號