如何在微服務中用戶權限策略?

作者 | Tyler Charboneau   譯者 | Sambodhi

策劃 | 閆園園  來源 | InfoQ 架構頭條

在當今的軟件工程領域,微服務架構占主導地位。雖然這種基礎設施方法有很多優點,但它已經形成了一個非常複雜的管理網絡。IBM 確認了這一點,共享該應用程序包含 “數十個、數百甚至數千個不同的、可獨立部署和可更新的服務”。除保持服務可靠性外,管理員還必須有效地管理數百個甚至數千個用戶的權限。

爲保證長期安全性、服務可用性和微服務可擴展性,設計清晰的用戶權限策略是必不可少的。你無法使用 “一扇搖擺的門” 來保護你的 API 端點。在會話過程中控制用戶看到和執行的操作是應用程序管理的基礎。

1 評估標準

本文介紹了微服務中一些有用的用戶權限策略,並對其進行了分解。這樣做可以幫助你瞭解哪些策略最適合你的組織的服務。對於每個權限策略,我們將基於以下要點評估:

這些標準構成了衡量策略有效性的強大基線。

2 權限策略簡介

對你的權限進行管理時,有兩種主要途徑,每一種都有其細微差別。首先,你可以選擇自己管理所有的權限,換句話說,你不需要依靠集中的第三方工具。這就是所謂的細粒度方法。採用這種方法的團隊通常想要對他們的部署有不受約束的控制。

無需深入研究策略(稍後將詳細介紹),可以根據用戶和應用程序之間的關係、會話設計、服務器安排和 API 依賴關係等因素選擇許多子方法。

相反,還有一種集中式服務的方法。一般情況下,這取決於對外部工具的集成和第三方服務的集成,這些服務在一定程度上保留了你的後端訪問的權限。這樣,你就可以使用統一的界面(包括命令行界面)來管理權限和角色。通常,對更改實際服務代碼的依賴較少;你的重點是配置。

每一個策略都各有利弊。用例也隨基礎設施的不同而不同。在這種情況下,讓我們深入研究。

策略 1:管理自己的權限

免責聲明:自我管理你的權限可能是一個費力的過程。但是,還需要做一些權宜之計,根據特定服務,對權限進行粒度控制。因爲你將承擔大部分設置工作,所以理解自我管理微服務架構所帶來的挑戰是值得的。

請記住,用戶的權限首先與身份驗證和授權密切相關。你的權限設置直接影響用戶會話從登陸到註銷的過程。如果將這些行爲擴展到多個用戶賬戶,則會出現一些明顯的障礙:

任何自治權限策略的前提是進行創造性地避開這些限制。有多種方法可以做到這一點,我們現在來探討一下。

無狀態會話管理

微服務通常最好是保持無狀態。多個容器都爲共享的資源池而競爭,尤其是當服務經歷了大量的用戶活動時。這些使用高峯將產生大量內存需求;因此,無狀態請求所需的內存開銷要小得多。這些新事物是輕量級和敏捷的。服務器還可以並行處理大量請求,提高了穩定性和性能。這在多個用戶同時登陸並訪問資源時非常重要。這對所有用戶來說都是相同的。

這就是說,我們可以通過三種方式將無狀態方法的好處與會話結合起來。

第一種是通過使用稱爲粘性會話(sticky session)的方法,在這個方法中,服務器會處理用戶最初請求,從而 ping 任何後續請求。負載均衡器對允許這種情況的發生至關重要,但只允許水平向擴展集羣。但是,這種添加機器的實例(而不是通過升級當前機器來向上擴展)更可取,因爲它允許成百上千的併發用戶會話。當然,這些會話需要基於它們的行爲進行身份驗證和重複授權。切記,在這種情況下,強制的服務器交換將轉儲用戶會話數據——要求重新登陸並訪問授權服務器。

第二種是會話複製(session replication),它是在網絡上保存用戶會話數據並同步的。對用戶數據的任何更改將自動推送到所有機器。所以,這種處理用戶的方法會消耗更多的資源,通常採用帶寬形式。這裏有很好的一致性;服務器不會忘記用戶的權限,或者忘記一個賬戶的後端關聯。遺憾的是,可擴展性相對有限。

第三種是集中式會話存儲(centralized session storage),它將用戶憑證和相關數據放在一個共享位置。登錄狀態保持不透明,這意味着服務器不會將憑證解釋爲純文本。這樣做對安全性來說是很好的。儘管可以擴展,但是這種方法需要共享存儲的保護機制。

客戶端令牌

令牌可以幫助微服務及其服務器之間的無狀態 - 有狀態衝突。令牌並非將用戶會話存儲在服務器上,而是作爲用戶身份細節的存儲容器。這在利用 cookie 的基於 Web 的服務中最爲常見。用戶將其令牌和會話信息保存在設備上。

通過使用這個令牌來確認所有用戶對服務器的請求,然後決定每個用戶的權限如何配合。這樣,用戶就可以看到、交互甚至修改哪些內容。不透明令牌是在某些情況下使用的專門令牌;對於 OAuth 來說,這些令牌是專有的,並且不可訪問,同時指向服務器上持久存儲的信息。OAuth 是一家流行的身份驗證服務供應商,它提供了管理 API 和自定義 API 訪問令牌。

此外,JSON Web 令牌(JWT)是一種流行的令牌格式,它是標準化的,並且基於三個元素構建。頭部包含了類型和哈希算法(因爲令牌必須加密)。有效負載包含用戶 ID、用戶名和到期日期。它還可以包含角色。最後,簽名將驗證令牌身份併爲客戶端提供驗證。令牌通常會在短時間後刷新來保持安全性,以防攻擊者竊取它們。

令牌化過程如下:

  1. 發出初始化登錄的 API 請求。

  2. 服務器創建令牌。

  3. 令牌返回到存儲它的客戶端瀏覽器。

  4. 當執行操作時,用戶通過頭部將令牌發送給服務器。

  5. 驗證簽名,並傳喚用戶信息。

  6. 向客戶端發送適當的響應。

令牌化還可以與 API 網關配對。請求並不直接進入服務器,而是通過中間網關審查操作並將其傳遞。微服務不會向用戶公開,不管是檢測出問題還是用戶註銷,網關可以撤銷令牌。在客戶端隱藏了授權令牌,因此無法如此輕鬆地解密。

單點登錄

單點登錄(Single sign-on,SSO)可能是最簡化的訪問管理方法,因爲它允許用戶的登錄驗證(身份驗證步驟)在一系列捆綁的服務中對同一個用戶進行認證。目前,應用程序通常在其功能範圍內承載多個服務。逐一登錄所有的服務,對用戶來說是非常乏味的。對所有服務的訪問都通過一個集中的認證服務進行路由。儘管在很多方面都很方便,但是這種方法很容易出錯或網絡流量激增。

互助式身份驗證

當服務處於活動狀態時,微服務通常彼此通信。這樣,互聯的微服務就會在用戶開展業務時共享大量流量。由於每個服務唯一的身份驗證證書是通過 TLS 交換的,所以雙向 SSL 連接允許相互身份驗證。應用實例不斷變化的的性質會對這個身份驗證過程造成麻煩,但是也有一些好消息:私有證書中心可以幫助確定如何爲所有適用的服務進行頒發、撤銷和更新證書。

忠告

所有這些選項中的共同缺點是易用性。每一種選項都有一定的取捨,並需要一定程度的手工設置才能成功。雖然內置的自動化可以間接地或直接簡化權限處理過程,但在你的團隊中需要特定的專業知識。合理地執行這些策略需要熟練掌握 API、安全性和微服務架構。經驗不足的人更容易犯錯,而這些錯誤會破壞權限處理。

諸如基於角色的訪問控制和基於屬性的訪問控制(attribute-based access control,ABAC)這樣的機制,都是活的概念,需要在服務的生命週期內持續地維護。很多情況下,自我管理的身份驗證和授權都可能會出問題。以不可見的方式實施(就用戶而言),也是系統安全的核心。糟糕的編碼解決方案可能會提供過多關於後端權限結構的信息。

開源資源能否緩解開發之痛?儘管在很多情況下答案是肯定的,但事實是,成功的整合仍然是一個挑戰。文檔並非 “百發百中”,跨語言的邏輯共享令人懷疑,而編碼工作可能很大。

身份驗證後授權用戶

當你的服務確定你(或你的用戶)是誰之後,它們將決定在應用程序中實際可以做什麼。可以單獨對每一個服務執行此操作,儘管這一過程需要一些時間,並且會帶來潛在的問題。

儘管有利安全性和細粒度控制,但這要求爲所有微服務重寫安全邏輯。這樣會導致臃腫的重複構建。這也會將每個服務與它沒有的外部授權數據連接起來。最終,隨着服務規模的擴展,這些零碎的設計在監控上變得更加複雜。

爲了避開這些核心問題,團隊通常會採用一個與每個服務共享的身份驗證庫的形式。他們還可以建立起將授權和身份驗證連接起來的全局服務——通常是通過授權數據庫。不幸的是,後一種方法使用全局服務來處理單個用戶角色。這些檢查會引起安全問題,並且會增加延遲。

有沒有更好的辦法處理授權呢?很多人認爲,集中式的服務對監督他們的團隊很有效,而且不需要太多的維護。這樣就避免了傳統 API 網關和單端點之間的強耦合問題。現有的第三方服務顯然簡化了這些步驟。

策略 2:使用集中式服務

雖然單個管理可能很複雜,但是集中式的方法可以提供你急需的簡單性。這種策略使用一箇中央微服務,將部署到現有應用程序中。這種形式一般採用補充式容器。

一些第三方服務,比如 Cerbos,甚至可以作爲 sidecar 來運行:它與相關的應用程序鬆散耦合,同時以鎖步方式完成基於權限的工作。這些 sidecar 很有用,因爲它們是基於現有服務進行擴展的。

提出授權和身份驗證請求的所有服務都是通過這種專門的權限微服務進行路由的。該響應返回到客戶端,以確定其請求是否成功。這個集中的部分強制執行了所有基於權限的決定。但是,如果同事運行多個節點,並且其中一個節點被分區,就可能會出現問題。

假定節點與其他系統節點有效分離。在集中式設置中,這個節點無法接受外部服務的任何權限決定。可能會失敗關閉——拒絕所有的身份驗證請求,或者失敗開放。後者是非常有問題的,因爲所有的身份驗證請求都被批准。失敗關閉會引起連鎖反應,即所有客戶對分區服務的請求都被拒絕。

在考慮像 Cerbos 這樣的東西時,值得慶幸的是,情況會變得更清晰一些。對於非開發者來說,這個解決方案非常友好,因爲它不需要了解任何規則和語言。權限邏輯的更改會自動推送到你的基礎設施的每個角落,從而節省時間和精力。這個解決方案沒有任何依賴性,仍然包含在本地網絡中。像這樣的集中式工具甚至可以在促進 GitOps 的同時確定角色。

集中式的服務在讓事情變得簡單時很有用。它們是微服務權限規則的單一真相來源,運行時不會使原本錯綜複雜的系統複雜化。現代衍生產品被設計用於容器化環境,並利用流行的 API 協議來有效地運行。

使用集中式服務會使沒有深厚權限安全知識的小團隊受益良多。儘管配置仍然很強大,但是在執行身份驗證和授權時,需要做的工作更少。如果你在整個部署過程中使用多個框架或語言,那麼集中式解決方案將使你能夠快速實施你所需的不可知性。其中甚至包括了一些非常有用的測試,因爲權限和微服務會隨着時間而變化。

維護成本自然也降低了。因爲中央服務可以向所有服務推送更改,你不必花費開發資源來分別更新每個服務。運行大量服務的組織可以從這一事實中得到一些安慰。

3 結論

在自我管理與集中化的較量中,選出一個贏家並不是那麼非黑即白。一個團隊對其基礎設施的舒適程度、某些技術和預算將決定適當的行動方案。即使是像 OAuth + JWT 這樣的流行設置,也是安全和可靠的,但它們並非萬無一失。一個集中式服務可以爲讓團隊在不太挑剔或者打擾的情況下檢查很多功能框。爲微服務設計強大的權限策略,通常是公司能採取的最困難的安全措施。這樣,集中化可以讓不是用普通的無狀態方法的團隊更容易地做到這一點。

原文鏈接:

https://cerbos.dev/blog/comparing-microservice-permissions-strategies


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