Open-Policy-Agent简化了微服务授权

25次阅读

共计 3258 个字符,预计需要花费 9 分钟才能阅读完成。

随着微服务的发展,经常遇到实施身份验证和授权(A&A)的问题。我们需要一个强大且集中管理的身份验证和授权策略。但是,应用程序的分布式性质使其难以实现。在本文中,我将探讨 Open Policy Agent 如何帮助简化授权问题。

让我们快速查看“身份验证和授权”的定义。认证 是指识别用户(“who”)。而 授权 是指确定经过身份验证的用户具有的访问级别(“what”)。

我这篇文章的重点是授权部分。为了简单起见,我创建了一个带有一组微服务的示例应用程序。有一个基本的用户界面,我们可以在其中执行各种操作并查看结果。该应用程序的唯一目的是显示 Open Policy Agent 如何处理各种授权方案。在后续文章中,我们将扩展该应用程序的范围,以涵盖日益复杂的用例和策略管理。

示例应用

首先,关于应用程序的一些上下文。我以销售团队通常使用的 CPQ 应用程序为客户配置报价为例。

有以下角色:

  1. 销售–具有“销售”角色的用户可以为其客户创建新报价并更新报价。但是,具有“销售”角色的用户不能删除商品。
  2. 销售支持–支持人员,他们可以查看所有报价,但不能编辑任何报价。、
  3. 销售管理员–行政人员可以查看所有报价,但不能编辑 / 创建任何报价。但是,如果需要确保清理,他们可以删除要约。

由于我们专注于授权部分,因此我假设用户已经过身份验证,并且具有有效的 JSON Web 令牌(JWT)。每个 API 请求都在请求标头中包含此 JWT。

在此处从 github 下载示例应用程序。按照自述文件中的安装说明进行操作,您应该可以使用 URL http://<MINIKUBE URL>/访问 UI。

授权实战

基于我们在上面看到的角色,期望销售团队能够

  • 创建新报价
  • 列出报价
  • 更新现有报价

而销售支持团队只能列出报价,而不能编辑 / 创建报价。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: 本文属于翻译,原文

正文完
 0