Open Policy Agent:簡化了微服務受權

隨着微服務的發展,常常遇到實施身份驗證和受權(A&A)的問題。咱們須要一個強大且集中管理的身份驗證和受權策略。可是,應用程序的分佈式性質使其難以實現。在本文中,我將探討Open Policy Agent如何幫助簡化受權問題。前端

讓咱們快速查看「身份驗證和受權」的定義。認證是指識別用戶(「who」)。而受權是指肯定通過身份驗證的用戶具備的訪問級別(「what」)。git

我這篇文章的重點是受權部分。爲了簡單起見,我建立了一個帶有一組微服務的示例應用程序。有一個基本的用戶界面,咱們能夠在其中執行各類操做並查看結果。該應用程序的惟一目的是顯示Open Policy Agent如何處理各類受權方案。在後續文章中,咱們將擴展該應用程序的範圍,以涵蓋日益複雜的用例和策略管理。github

示例應用

首先,關於應用程序的一些上下文。我以銷售團隊一般使用的CPQ應用程序爲客戶配置報價爲例。json

有如下角色:api

  1. 銷售–具備「銷售」角色的用戶能夠爲其客戶建立新報價並更新報價。可是,具備「銷售」角色的用戶不能刪除商品。
  2. 銷售支持–支持人員,他們能夠查看全部報價,但不能編輯任何報價。、
  3. 銷售管理員–行政人員能夠查看全部報價,但不能編輯/建立任何報價。可是,若是須要確保清理,他們能夠刪除要約。

因爲咱們專一於受權部分,所以我假設用戶已通過身份驗證,而且具備有效的JSON Web令牌(JWT)。每一個API請求都在請求標頭中包含此JWT。服務器

在此處從github下載示例應用程序。按照自述文件中的安裝說明進行操做,您應該可使用URL http://<MINIKUBE URL>/訪問UI。app

受權實戰

基於咱們在上面看到的角色,指望銷售團隊可以curl

  • 建立新報價
  • 列出報價
  • 更新現有報價

而銷售支持團隊只能列出報價,而不能編輯/建立報價。 Sales Admin團隊只能列出報價並將其刪除。分佈式

UI顯示了多個按鈕,每一個按鈕表明用戶的操做。選擇您要使用的角色,而後嘗試建立,編輯或刪除商品。 UI將提供有關操做是否成功的反饋。函數

那麼,這裏發生了什麼?

讓咱們快速瞭解一下當前的設置。

該應用程序具備兩個微服務優惠和客戶。 NGINX反向代理將這些API公開給外界。 NGINX截獲每一個API請求並請求受權服務以驗證是否容許用戶執行請求的操做。咱們使用NGINX的auth_request指令來攔截傳入的API調用。每一個API調用都有一個Authorization標頭,其中包含JWT。包括角色在內的整個用戶信息都包含在JWT中。

受權服務有兩個容器:

  1. 受權–一種定製服務(Authorization),用於接收請求併爲Open Policy Agent建立格式化的輸入請求。
  2. 開放策略代理(OPA)–做爲輔助工具運行,並公開http端點以與受權容器進行通訊。

基本上,NGINX將/authorize請求發送到Authorization容器以受權API調用。而後,受權服務諮詢開放策略代理是否受權請求(是/否)。而後,它向NGINX返回成功(200 OK)或錯誤(403 Forbidden)響應。所以,NGINX容許API調用或向客戶端返回403 Forbidden響應。

Open Policy Agent 是什麼?

Open Policy Agent(OPA,發音爲「 oh-pa」)是一種開放源代碼的通用策略引擎,它統一了整個堆棧中的策略執行。 OPA提供了一種高級的聲明性語言,可以讓您將策略指定爲代碼和簡單的API,以減輕軟件決策的負擔。您可使用OPA在微服務,Kubernetes,CI / CD管道,API網關等中實施策略。

基本上,OPA將決策與執法脫鉤。它接受結構化數據做爲輸入(JSON),而且能夠返回決策(對/錯)或任意結構化數據做爲輸出。

OPA使用rego做爲策略語言。您能夠在https://www.openpolicyagent.org/docs/latest/上了解有關rego和開放策略代理的更多信息。

受權服務詳解

讓咱們詳細查看受權服務,以瞭解其工做原理。

咱們在服務器模式下運行Open Policy Agent,並利用其REST API更新策略並獲取策略決策。

  • Open Policy Agent公開REST API來建立或更新策略。
PUT /v1/policies/<id>
Content-Type: text/plain

對於咱們的示例,使用帶有如下請求的終結點(在GitHub README中也提到了)來更新OPA中的策略。

curl -X PUT --data-binary @policies/httpapi.authz.rego http://<MINIKUBE URL>/authorize/v1/policies/httpapi/authz
  • 要根據此政策作出決定,還有另外一個API
POST /v1/data/<path>
Content-Type: application/json

這裏的<path>是由軟件package標識的策略的路徑,例如package httpapi.authz。對於咱們的示例,要刪除商品ID「 1000」,受權服務將使用如下請求正文調用端點http://localhost:8181/data/httpapi/authz:

{
    "input" : {
        "method": "DELETE",
        "api": "/offer/1000",
        "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NzQ2NjM3MDAsImV4cCI6NDA5OTE4NTMwMCwiYXVkIjoib3BhLWV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjoiU2FsZXMgQWRtaW4ifQ._UtjZtowF3NNN3IF1t0LBHuzQhdfIfsO8jC-46GvbRM"
    }
}
  • 受權應用程序將接收來自NGINX的請求,並如上所述生成對OPA的輸入請求。爲了這個示例,我已經在前端代碼中對JWT進行了硬編碼。每一個API請求都在Authorization標頭中包含JWT。受權應用程序將提取JWT並將其添加到OPA的輸入請求中。
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMb2NhbEpXVElzc3VlciIsImlhdCI6MTU3MzcyNzM5MSwiZXhwIjo0MDk4MjQ1Mzc4LCJhdWQiOiJvcGEtZXhhbXBsZS5jb20iLCJzdWIiOiJzYWxlc0BleGFtcGxlLmNvbSIsIkdpdmVuTmFtdyI6IkpvaG5ueSIsIlN1cm5hbWUiOiJTYWxlcyIsIkVtYWlsIjoianNhbGVzQGV4YW1wbGUuY29tIiwiUm9sZSI6IlNhbGVzIn0.UbHWQpCMwupzsFp8f0CQ4o_bJSVaBugKijhcURZ_Mko
  • 請注意,受權服務僅從傳入請求中檢索JWT,而不會對其進行解碼。 OPA經過內置函數io.jwt.decode支持JWT的解析。
  • 您能夠在這裏在rego操場上嘗試咱們用於本示例的rego策略。嘗試不一樣的輸入請求,您將看到OPA爲每一個輸入請求生成的輸出。

結論

所以,簡而言之,Open Policy Agent提供了一種將受權決策與微服務中的業務邏輯分離的方法。系統管理員能夠設置Open Policy Agent,並將生成受權策略(重發策略)的責任委託給各個微服務全部者。微服務全部者和系統管理員都不會處理其邊界以外的區域。

PS: 本文屬於翻譯,原文

相關文章
相關標籤/搜索