資源鑑權的選型,不能只看“鑑權代碼應該放在哪裡”,還需要結合權限粒度、請求併發、數據一致性、系統可用性和運維複雜度綜合判斷。

需要先區分幾個概念:

  • 認證:確認訪問者是誰。
  • 令牌校驗:驗證 Access Token 的簽名、發行方、受眾和有效期。
  • 授權決策:判斷訪問者是否有權限執行某項操作。
  • 權限執行:將授權結果應用到具體接口、資源或數據。

Spring Authorization Server 是基於 Spring Security 構建的 OAuth 2.0 和 OpenID Connect 授權服務器實現,負責授權流程以及 Access Token、Refresh Token 等令牌的簽發,並可與用戶認證流程集成。它並不等同於資源鑑權服務。

在微服務系統中,可以從“授權決策在哪裡完成、權限檢查在哪裡執行”兩個維度,討論三種常見模式。它們可以組合使用,並不是互斥的選項。

一、網關入口鑑權

網關鑑權適合權限規則相對簡單的場景。

網關通常負責:

  1. 校驗 Access Token;對於 JWT,驗證簽名、發行方、受眾和過期時間;
  2. 根據業務要求檢查令牌是否被撤銷,或賬號是否處於可用狀態;
  3. 根據路由、角色或 Scope 執行基礎訪問控制;
  4. 執行黑名單、白名單、限流等入口策略。

對於只要求“令牌合法且接口允許訪問”的系統,網關可以完成大部分鑑權工作。如果業務服務只允許通過可信網關訪問,並能驗證網關傳遞的身份信息,就可以複用入口的基礎校驗結果。若服務存在其他訪問入口,則仍需要獨立驗證身份和權限。

這種模式的優點是:

  • 不合規請求可以在系統入口被攔截;
  • 業務服務的鑑權代碼較少;
  • 入口權限規則集中,便於統一管理;
  • 可以減少無效請求進入內部網絡。

但隨著權限粒度變細,網關可能需要查詢用戶、角色、組織、資源和數據權限等信息。此時,如果每次請求都訪問數據庫或集中式權限服務,鑑權鏈路就可能成為系統瓶頸。

網關集群和負載均衡可以解決網關節點自身的 CPU、連接數和吞吐問題,但不能自動解決權限查詢瓶頸。實際部署中通常還需要配合:

  • 權限策略緩存;
  • 本地 Token 校驗;
  • 批量查詢;
  • 權限數據預加載;
  • 鑑權超時與故障處理策略;
  • 集中式權限服務的高可用部署。

因此,網關鑑權並不等於“所有權限都必須在網關完成”。複雜的數據權限通常仍需要由業務服務在內部進一步判斷。

二、集中式授權決策

集中式授權決策是指將權限策略管理和授權決策交給一個獨立的權限服務或策略引擎。網關或業務服務向它提交主體、資源、操作和上下文信息,再由權限服務返回允許或拒絕的結果。

典型流程如下:

客戶端請求
    ↓
網關或業務服務
    ↓
權限服務 / 策略引擎
    ↓
返回允許或拒絕
    ↓
網關或業務服務執行權限檢查

這種模式的優勢在於:

  • 權限規則集中維護;
  • RBAC、ABAC 等複雜策略可以統一實現;
  • 不同業務服務使用相同的權限模型;
  • 權限變更不需要同時修改所有業務服務。

但集中式決策也會引入新的依賴:

  • 每次鑑權可能增加一次網絡調用;
  • 權限服務故障可能影響大量業務請求;
  • 高併發場景下,權限服務可能成為集中瓶頸;
  • 權限決策緩存會帶來一致性和失效問題。

因此,集中式權限服務需要重點設計緩存、超時、熔斷和高可用。故障處理必須明確:無法獲得有效授權結果時,受保護的操作應默認拒絕;如果允許複用緩存結果,則需要限定適用操作、緩存有效期和權限撤銷的生效窗口。

對於要求權限變更立即生效的操作,僅縮短緩存時間仍不夠,還需要同步查詢或能夠保證及時失效的機制。對於允許短暫延遲生效的普通權限,則可以使用更長的本地緩存週期。

集中式策略管理不一定意味著每次請求都必須遠程調用。常見的優化方式是:

  • 集中管理策略;
  • 將策略同步到網關或業務服務本地;
  • 在本地執行大部分決策;
  • 只有複雜或特殊場景才訪問中心服務。

此時,策略管理仍然集中,而授權決策的執行已經部分下沉到本地。

三、服務本地鑑權與分佈式策略同步

當權限粒度深入到業務接口、業務操作甚至數據行級別時,僅依靠網關通常不夠。此時可以由各個微服務在 Controller、Service 或方法安全層執行本地鑑權。

例如:

@PreAuthorize("@permission.canAccess(authentication, #orderId)")
public OrderDetail getOrderDetail(Long orderId) {
    return orderService.getDetail(orderId);
}

此時請求仍然會經過網關,但具體的業務權限由目標微服務結合本地業務數據完成判斷。

這種模式的優點是:

  • 權限判斷可以使用最接近業務的數據;
  • 更適合數據權限、資源所有權和操作級權限;
  • 鑑權負載可以隨業務請求分散到各個服務;
  • 網關可以專注於路由、基礎令牌校驗和入口控制。

代價也比較明顯:

  • 若入口沒有先做基礎校驗,不合規請求會進入內部網絡,增加流量消耗;
  • 每個服務都需要實現或接入鑑權能力;
  • 不同服務之間可能出現權限規則不一致;
  • 權限模型升級和策略發佈更加複雜;
  • 必須防止繞過 Controller 或內部接口直接訪問業務邏輯。

服務本地鑑權通常需要遵守幾個原則:

  • 默認拒絕,明確授權;
  • 按訪問入口覆蓋權限檢查,不能只依賴某一個 Controller 切面;
  • 服務間調用也要驗證調用方身份,並根據操作檢查權限;
  • 權限判斷不能只依賴客戶端傳入的參數;
  • 權限緩存必須具備過期和失效機制;
  • 策略更新需要能夠及時同步到各個實例。

權限配置可以集中保存在數據庫或配置中心,再通過發佈訂閱機制通知各個服務刷新本地緩存。這個過程更適合稱為“集中式策略存儲與分佈式緩存同步”,不必強行歸類為黑板架構。

四、三種模式的對比

模式 主要決策或執行位置 優勢 主要代價
網關入口鑑權 網關 入口攔截早、規則集中、服務改造少 網關負載集中,難以處理複雜業務權限
集中式授權決策 權限服務或策略引擎決策,調用方執行 權限模型統一,適合複雜策略 增加網絡依賴,存在中心瓶頸
服務本地鑑權 業務微服務 接近業務數據,適合細粒度權限 需要解決策略一致性與檢查覆蓋問題

實際系統很少只採用一種模式,更常見的是組合使用:

客戶端請求
    ↓
網關:Token 校驗、路由級權限
    ↓
業務服務:資源權限、數據權限、操作權限
    ├── 基於本地策略和業務數據判斷
    └── 必要時調用權限服務進行復雜策略決策
    ↓
允許後執行業務操作

例如,網關可以拒絕無效令牌和沒有基礎 Scope 的請求,業務服務再判斷用戶是否擁有某個訂單、賬戶或組織的數據權限。

五、架構選擇需要權衡的質量屬性

微服務授權設計本質上是一個架構權衡問題。它至少會影響以下質量屬性:

  1. 延遲:是否需要額外的遠程鑑權調用;
  2. 吞吐:鑑權邏輯會集中在網關、權限服務,還是分散到業務服務;
  3. 可用性:權限服務故障時,業務請求是否仍可安全處理;
  4. 一致性:權限變更需要多長時間才能在所有節點生效;
  5. 安全性:是否存在繞過網關、偽造身份或使用過期權限的問題;
  6. 可擴展性:是否支持更細的角色、資源和數據權限;
  7. 運維複雜度:策略發佈、緩存失效和問題排查是否可控;
  8. 流量與成本:無效請求是否會進入內部服務,鑑權調用是否造成額外資源消耗。

因此,權限粒度越細,並不意味著所有鑑權都應該下沉到業務服務;併發越高,也不意味著所有鑑權都應該集中到網關。

更合理的做法是:

  • 在網關完成低成本、通用的入口校驗;
  • 在業務服務完成依賴業務數據的細粒度權限判斷;
  • 使用集中式策略管理保證規則統一;
  • 通過本地緩存和事件同步降低遠程鑑權開銷;
  • 根據一致性要求設計緩存失效和權限變更機制。

架構設計沒有絕對完美的授權方案。真正需要回答的問題是:系統需要多細的權限粒度,需要多高的吞吐和可用性,以及權限變更允許多長時間的延遲。只有明確這些約束,才能決定鑑權應該集中在哪裡、執行在哪裡,以及哪些能力值得為之承擔額外的複雜度。