盤點微服務架構下的諸多身份驗證方式
聯合作者:羅澤軒,API7.ai 技術專家、Apache APISIX PMC 成員
聯合作者:趙士瑞,API7.ai 技術工程師,Apache APISIX Committer
身份認證是授予使用者訪問系統並授予使用系統的必要許可權的過程。而提供了這一功能的服務,就是身份認證服務。
在傳統的單體軟體應用程式中,所有這些都發生在同一個應用程式中。但在微服務架構中,系統由多個服務組成,在這樣的架構中,每個微服務都有自己的任務,因此為每個微服務分別實現授權和身份驗證過程並不完全符合此原則。
本文將從傳統服務架構和微服務架構下的身份認證方式區別進行討論,並最終衡量微服務架構中身份認證服務的各種實現方式的優劣。
傳統服務架構中的身份認證服務
在企業開發服務的早期,所有功能都是做到同一個應用程式裡面的。我們把這種模式稱之為 “單體”,以跟當下更為主流的 “微服務” 架構區分開來。
單體應用由單個不可分割的單元組成。它通常由各個業務線各自開發,但是部署時放入到同一個環境中。所有這些都緊密整合以在一個單元中提供所有功能。這一單元裡擁有所需的所有資源。單體應用的好處在於部署迭代簡單,適合業務線較少且比較獨立的公司採用。
隨著企業開發出來的業務越來越複雜,我們會發現單體服務已經無法滿足現實生活裡面快速迭代的需要了。我們需要把這個單體的巨無霸拆分一下,同時保證現有的各個功能間的呼叫能正常進行。這時候,ESB(企業服務匯流排)便應運而生了。
所謂的 “企業服務匯流排”,就是一根連線各個企業服務的管道。ESB 的存在是為了整合基於不同協議的不同服務,ESB 做了訊息的轉化、解釋以及路由的工作,以此來讓不同的服務互聯互通。從名稱就能知道,它的概念借鑑了計算機組成原理中的通訊模型 —— 匯流排,所有需要和外部系統通訊的系統,統統接入 ESB,就可以利用現有的系統構建一個全新的松耦合的異構的分散式系統。
ESB 做了訊息的轉換解釋與路由等工作,讓不同的服務互聯互通。傳統的 ESB 的服務呼叫方式是,每一次服務的呼叫者要向服務提供者進行服務互動請求時都必須通過中心的 ESB 來進行路由。
接下來將按照這兩種情況,分別描述對應的身份認證功能的實現。
單體架構
單體架構下,使用者身份驗證和會話管理相對簡單。身份認證和授權發生在同一個應用程式中,通常使用基於 session 的認證方案。一旦通過身份驗證,就會建立一個會話並將其儲存在伺服器上,任何需要它的元件都可以訪問它並用於通知和授權後續要求。會話 ID 被髮送到客戶端並用於應用程式的所有後續請求,以將請求與當前會話相關聯。
ESB 架構
在 ESB 架構下,所有使用者與服務之間,服務與服務之間全部通過 ESB 匯流排進行處理。由於 ESB 的架構是從單體拆分下來的,身份認證方式相對於單體架構並沒有變化。
微服務架構中的身份認證服務
從單體架構遷移到微服務架構有很多優勢,但微服務架構作為一種分散式架構,會存在更大的攻擊面,共享使用者上下文更加困難。因此微服務架構下需要有跟傳統架構不一樣的身份認證服務,才能響應更大的安全性挑戰。
目前,我們可以把微服務架構下的身份認證服務分為以下三類:
- 通過每個微服務實現身份認證;
- 通過身份認證服務實現身份認證;
- 通過閘道器實現身份認證。 當然,每種做法都有自己特定的優缺點。
通過每個微服務實現身份認證
既然微服務架構是從單體架構拆分出來的,因此比較自然的過渡方式就是由每個微服務自己實現身份認證。
每個微服務都需要實現自己獨立的安全性保障,並在每個入口點上強制執行。此方法使微服務團隊能夠自主決定如何實現其安全解決方案。但是,這種方法有幾個缺點:
- 安全邏輯需要在每個微服務中重複實現,這會導致服務之間的程式碼重複。
- 它分散了開發團隊的注意力,使其無法專注於其主要服務。
- 每個微服務都依賴於它不擁有的使用者身份驗證資料。
- 很難維護和監控。 完善這個解決方案的選擇之一就是使用一個載入在每個微服務上的共享認證庫。這個操作可以防止程式碼重複,開發團隊將只關注他們的業務領域,但仍然存在這種改進無法解決的缺點。
因為共享的認證庫仍然需要有對應的使用者身份資料,而且還需要保證各個微服務使用同樣版本的認證庫。老實說,共享認證庫更像是服務拆分不透徹的結果。
因此這種方式總結來說,優勢在於實施速度快,獨立性強;而劣勢也比較明顯,服務之間的程式碼重複、違反單一職責原則,較難維護。
通過身份認證服務實現身份認證
既然每個微服務自己實現身份認證難以維護,而使用共享認證庫又違背了微服務拆分的本意,那麼能不能把共享認證庫升級成專門的身份認證服務呢?
在這種情況下,所有訪問都通過同一服務進行控制,類似於單體應用裡面的身份認證功能。每個業務服務都必須在執行操作時,向訪問控制模組傳送單獨的授權請求。
但是,這種方法在一定程度上減慢了服務的執行速度,並增加了服務之間的互連量。並且各個微服務會依賴這個“單點”的身份認證服務。萬一統一的身份認證服務出問題,會造成鏈式反應,帶來二次傷害。
所以總結來看,這種方式雖然確保了每個微服務職責單一,使得身份認證功能更加集中。但是仍會造成單點依賴,進而增加請求延遲。
通過閘道器實現身份認證
遷移到微服務體系結構時,需要回答的問題之一是微服務之間如何通訊。前面提到的 ESB 是種方案,但是更常見的選擇則是採用 API 閘道器。
API 閘道器是所有請求的單個終端節點入口,它通過充當使用這些微服務的中央介面來提供靈活性。某個需要訪問其他微服務的微服務(以下稱之為“客戶端”,以跟被它訪問的微服務相區分)無權訪問多個服務,而是需要向負責將其路由到上游服務的 API 閘道器傳送請求。
由於 API 閘道器位於客戶端訪問的必經之路上,因此它是強制實施身份驗證問題的絕佳選擇。使用 API 閘道器可以減少延遲(呼叫身份驗證服務),並確保身份驗證過程在整個應用程式中保持一致。
舉個例子,通過 APISIX 的 jwt-auth 外掛,我們可以在閘道器上實現身份認證。
首先,我們需要規劃若干個使用者身份資訊(名稱、金鑰等等),並將其配置到 APISIX 上。 其次,根據給定的使用者金鑰,向 APISIX 發起簽名請求,得到這個使用者的 JWT token。 接著,當客戶端需要訪問某個上游服務時,帶上 JWT token,由 APISIX 作為 API 閘道器代理該訪問。 最後,APISIX 會通過 JWT token,完成身份認證的操作。
當然,凡事有利就有弊,沒有完全無劣勢的技術選型。使用閘道器來完成身份認證,還是帶來了少許單點問題。比起在每個微服務內完成身份認證,在閘道器上解決該問題,安全性相比會降低些。比如 API 閘道器被攻破之後,就可以訪問該閘道器背後的任何微服務。但是風險是相對的,比起統一的身份認證服務,使用 API 閘道器的單點問題並沒有那麼嚴重。
因此這種方式操作起來,在優勢上較為明顯,比如可以有效保護後端微服務,微服務不用處理任何認證邏輯等。但同時還是會存有少許的單點依賴。
總結
在不同的場景下,我們會需要不同的身份認證方案。在單體應用中,身份認證發生在同一個應用程式中,服務端儲存了所有的會話。進入微服務時代,單體應用演變為分散式服務,單體應用中的身份認證方式在微服務中並不適用。在微服務架構中,我們有上述提到的三種身份認證的方式可供選擇。每種選擇都有屬於自己的利弊,需要根據具體的實際情況做具體分析。
- RESTful API 為何成為頂流 API 架構風格?
- APISIX Ingress 如何使用 Cert Manager 管理證書
- API 閘道器策略的二三事
- 服務網格領域的百花齊放,是否存在一個更優解?
- 馬蜂窩如何利用 APISIX 閘道器實現微服務架構升級
- 為什麼 APISIX Ingress 是比 Ingress NGINX 更好的選擇?
- 基於 APISIX 的服務網格方案 Amesh 積極開發中!
- 盤點微服務架構下的諸多身份驗證方式
- 2022 Apache APISIX 年度記憶
- APISIX Ingress 對 Gateway API 的支援和應用
- 為什麼 APISIX Ingress 是比 Traefik 更好的選擇?
- 當 Amazon Lambda 遇上 Apache APISIX 可以擦出什麼火花?
- 認證鑑權對於 API 閘道器的重要性
- 馬斯克都不懂的 GraphQL,API 閘道器又能對其如何理解?
- APISIX Ingress 如何支援自定義外掛
- Apache APISIX 玩轉 Tongsuo 國密外掛
- 如何基於 APISIX 迭代數字智聯平臺
- 譯文 | A poor man's API
- APISIX 在君潤人力雲原生平臺的架構實踐