微服務下的身份認證和令牌管理

分佈式和微服務架構已經越來越多的應用在企業中,服務間的身份認證和令牌管理是其必不可少的部分。我們的團隊在構建一站式門戶站點時,需要集成多個後端微服務,每一個服務需要訪問不同的系統來完成對應的業務場景 (比如:訂單系統,偏好推薦系統,產品系統等)。我們需要將這些系統有機的進行整合,通過在項目中的不斷實踐,配置恰當的身份認證和令牌管理,我們總結了一些微服務間的身份認證、令牌管理的架構演進與最佳實踐。

背景

我們的系統是使用微服務架構開發並打包到容器中,這些系統部署在 Kubernetes(它是用於自動化部署,擴展和管理容器化應用程序的開源系統。它將組成應用程序的容器分組爲邏輯單元,以便於管理和發現)。在這些站點中,前端系統需要攜帶令牌訪問不同服務,每一個服務需要攜帶令牌訪問不同的下游服務來完成相應的業務場景,所以這個過程涉及到各個服務之間的身份認證和令牌管理。系統架構涉及到多個微服務,這些微服務系統由不同的團隊維護,我們引進了不同的方案來解除各個系統在鑑權上的耦合,降低系統的複雜性,提高鑑權的可複用性和可維護性。本文我們將結合項目中引進的系統自身鑑權,API 網關鑑權和 authentication sidecar 模式,介紹整個上下游服務之間的身份認證、令牌管理的架構演進與最佳實踐。

系統自身鑑權

系統自身鑑權,就是每個應用系統自己進行身份認證和令牌管理,下面我們就從 Inbound Authentication 和 Outbound Authentication 來分析。Inbound Authentication

上圖是入站身份驗證流程,服務消費者調用 Service 時,Service 作爲服務提供者需要對消費者的令牌進行驗證。具體流程如下:

  1. 服務消費者從 OAuth 服務器獲取令牌

  2. 服務消費者攜帶令牌調用 Service

  3. API 請求流入 Service 中

  4. Service 從 OAuth 服務器獲取公鑰,驗證令牌是否有效。公鑰用於驗證令牌數字簽名。如果令牌有效,則在 Service 中進行業務處理

Outbound Authentication

這是本地的出站請求流程,Service 作爲服務消費者攜帶令牌訪問其他後端服務。具體流程如下:

  1. Service 通過 client id 和 client secret 調用 OAuth 服務器獲得令牌

  2. Service 攜帶令牌請求後端微服務

問題和挑戰

從耦合性,複雜性,可複用性,可維護性四個維度來看,現在的 inbound 和 outbound authentication 流程面臨如下問題:

如何來解決這些問題呢,API Gateway 是選項。

API 網關鑑權

什麼是 API 網關

API 網關位於客戶端與各個微服務間,充當了反向代理的角色,將客戶端請求路由到相應的微服務。與此同時,它可以完成安全,限流,緩存,日誌,監控,重試,熔斷等功能。API 網關方式的核心要點是,所有的接入方和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能。身份認證作爲 API 網關中的一個組件,可以以模塊的方式運行,也可以用微服務的方式運行。

Inbound Authentication

如上圖所示,當服務消費者需要請求服務提供者時,

  1. 服務消費者請求 OAuth 服務器獲得訪問服務端的令牌

  2. 服務消費者攜帶令牌調用服務端,該 API 請求會先經過 API 網關

  3. API 網關的身份認證服務獲取公鑰對令牌進行驗證

  4. 如果令牌有效,那麼請求將流向相關的服務提供者

相比於微服務系統自身鑑權,API 網關鑑權可以來進行 Inbound Authentication,從耦合性,複雜性,可複用性,可維護性四個維度來看比系統自身鑑權都有所改善。

問題和挑戰

API 網關沒有處理 Outbound Authentication,服務提供者還是需要在自己服務端獲取令牌來訪問其他服務,所以令牌管理的耦合性,複雜性,可複用性,可維護性問題沒有解決。另外如果 API 網關和服務提供者是通過網絡通信,那麼根據 “零信任網絡,永遠不要信任網絡並始終進行驗證” 原則,我們還是需要在 API 網關和服務提供者實施安全控制,增加了鑑權的複雜性。針對這些問題,Thoughtworks 技術雷達裏面收錄了一種處於試驗階段的方案 sidecars-for-endpoint-security,後面我們就叫它 authentication sidecar pattern。

Authentication Sidecar Pattern

什麼是 Sidecar Pattern

Sidecar 模式是一種解耦的模式,比較適合系統運行在日益複雜的多雲或混合雲環境中,其中包含多個分佈式組件和服務。如這些組件和服務是使用微服務架構開發並打包到容器中,部署在 Kubernetes,Kubernetes 將組成應用程序的容器分組爲邏輯單元,以便於管理和發現。

如上圖所示,sidecar 附加到 Service 併爲 Service 提供支持功能。Sidecar 位於與 Service 相同的 Kubernetes Pod 中,並與 Service 共享相同的生命週期,與 Service 一起創建和淘汰。Ingress sidecar 用於處理到附加到 Service 的入站請求。Egress sidecar 用於處理 Service 到下游 Service 的出站請求。下面會通過對比系統自身鑑權和 authentication sidecar 模式,來對 authentication sidecar 進行分析。

Inbound Authentication Sidecar

上半部分的圖是系統自身鑑權的入站身份認證流程,首先服務消費者從 OAuth 服務器獲取令牌,然後攜帶令牌調用 Service, Service 驗證令牌。下半部分的圖是 authentication sidecar 的身份認證。基礎設施級別: Kubernetes 的 Pod 有一個 ingress sidecar 負責驗證入站的令牌,authentication SDK 從 Service 分離並放入 ingress sidecar。整體的流程:

  1. Ingress sidecar 啓動時從 OAuth 服務器中獲取公鑰或者證書,服務消費者請求 OAuth 服務器獲得訪問後端 Service 的令牌

  2. 服務消費者攜帶令牌調用 Service

  3. 服務消費者的請求會通過 Secure API 會流入到 ingress sidecar 來驗證令牌。如果令牌驗證失敗,則 sidecar 拒絕該請求

  4. 如果令牌有效,那麼請求將流向 Service

此外,Service 中還有一個用於運行狀況檢查的 Health check API。我們可以看到 ingress sidecar 的特性:

  1. Service 中不需要 authentication SDK 了

  2. Sidecar 啓動時首先獲取公鑰並緩存起來,sidecar 可以基於本地緩存的公鑰對令牌進行驗證,而不是通過網絡訪問 OAuth 服務器進行驗證

Outbound Authentication Sidecar

左半部分是系統自身鑑權系統出站請求流程,首先 Service 從 OAuth 服務器獲取令牌,然後攜帶令牌調用其他後端微服務。右半部分是 authentication sidecar 的 authentication token 的管理。基礎設施級別: Kubernetes 的 Pod 有一個 egress sidecar 負責獲取出站令牌,authentication SDK 從 Service 分離並放入 egress sidecar。整體的流程:

  1. Service 的請求先流向 egress sidecar

  2. 如果 egress sidecar 緩存中沒有令牌,則 sidecar 獲取令牌並將其緩存起來。當 token 過期時,它支持自動刷新 token

  3. 如果 sidecar 緩存中有令牌,則不需要請求 OAuth 服務器。然後將 API 請求攜帶令牌路由到其他後端微服務

我們可以看到 egress sidecar 的特性:

  1. Service 中的 authentication SDK 是不需要的

  2. 當 Service 調用下游時,egress sidecar 會向 API 請求頭添加令牌。因爲令牌存儲在 sidecar 緩存中,不需要每次都調用 OAuth 服務器。當令牌過期時,自動刷新令牌。

Authentication sidecar 的全景圖

上面是整個請求的全景圖,上游可以是前端或後端服務消費者,Service 是自己團隊的應用程序,下游是服務提供者。Ingress 和 egress sidecar 有獨立的容器,和 service 容器一樣都位於同一個 Pod。

Authentication Sidecar 的好處

上圖是系統自身鑑權到 authentication sidecar 的架構演進, 從耦合性,複雜性,重複實現,可維護性四個維度來看:

  1. 耦合性:解除了業務系統和 authentication 的耦合,消除了應用 Service 中的關於身份認證和 authentication token 管理的重複實現,每個業務 Service 無需實現相同的身份驗證流程,只需在 kurbernets 的配置文件中對其進行配置。

  2. 複雜性:降低應用系統的複雜性,它將 authentication 委派給與業務系統部署在同一 Pod 中的進程外 sidecar,這樣自己的業務系統可以更專注於自身的業務。

  3. 可複用性:身份認證和 token 管理標準化,與編程語言無關。每個 Service 不需要實現相同的認證流程。企業內的團隊都可以輕鬆複用該 sidecar 來進行身份認證和 token 的管理。

  4. 可維護性:只有一個 code base,使得該 authentication sidecar 可以成爲企業內部的開源項目,易於進行 OAuth 服務的升級和替換,升級替換時只需要在 authentication sidecar 的 code base 進行改動就可以了。

總結

本文分析了微服務間身份認證和令牌管理的系統自身鑑權,API 網關鑑權和 authentication sidecar 的方案,痛點和好處。軟件工程中不可能有任何 “銀彈” 解決軟件的複雜度問題,這幾種方案都有相關的條件和限制,下表是關於這三種方案的適用場景。

Jn95ZI

針對現在分佈式,微服務,容器化架構的流行,許多系統運行在日益複雜的多雲或混合雲環境中,其中包含多個分佈式組件和服務。通過引入 authentication sidecar,使得各自團隊負責的 Service 代碼更加簡潔,解除了業務 Service 和 authentication 服務的耦合,在每一個的 Service 中消除了重複的 authentication 代碼,有利於分佈式和微服務系統的快速構建,開啓了分佈式和微服務架構的新體驗。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/dHnjXnzu2dOmtf7nL6WIag