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: 本文属于翻译,原文

相关文章
相关标签/搜索