管理 API 网关

Red Hat 3scale API Management 2.8

中等到高级目标,以管理您的安装。

摘要

本指南提供有关配置任务的信息,可在基本安装之后执行。

前言

本指南帮助您将中间到高级配置功能应用到 3scale 安装中。有关安装的基本详情,请参阅安装 3scale。

部分 I. API 网关

第 1 章 操作 APIcast

本节介绍了使用高级 APIcast 配置时需要考虑的概念。

1.1. 公共基本 URL

Public Base URL 是开发人员用于向 API 产品发出请求的 URL,通过 3scale 公开。这将是您的 APIcast 实例的 URL。

如果您使用的是由管理的部署选项之一,您可以在要管理的域名中为每个环境选择您自己的公共基本 URL。这个 URL 应与其中一个 API 后端不同,并可能类似 https://api.yourdomain.com:443,其中 您的domain.com 是您所属的域。设置公共基本 URL 后,请确保保存更改,如有必要,将暂存中的更改提升到生产环境。

注意

您指定的公共基本 URL 必须使用 OpenShift 集群中可用的端口。默认情况下,OpenShift 路由器仅侦听标准 HTTP 和 HTTPS 端口(80 和 443)上的连接。如果您希望用户通过某些其他端口连接到您的 API,请与您的 OpenShift 管理员合作以启用该端口。

APIcast 将仅接受对公共基本 URL 中指定的主机名的调用。例如,如果您将 https://echo-api.3scale.net:443 指定为公共基本 URL,则正确的调用是:

curl "https://echo-api.3scale.net:443/hello?user_key=YOUR_USER_KEY"

如果您的 API 没有公共域,您可以在请求中使用 APIcast IP 地址,但您仍需要在公共基础 URL 字段中指定一个值,即使该域不是真实的。在这种情况下,请确保在 Host 标头中提供主机。例如:

curl "http://192.0.2.12:80/hello?user_key=YOUR_USER_KEY" -H "Host: echo-api.3scale.net"

如果您在本地机器上部署,您也可以只使用"localhost"作为域,因此公共基本 URL 类似如下,然后您可以按照以下方式发出请求:http://localhost:80

curl "http://localhost:80/hello?user_key=YOUR_USER_KEY"

如果您有多个 API 产品,请为每个产品正确设置此公共基本 URL。APIcast 将基于主机名路由请求。

1.2. 映射规则

根据对 API 的请求,映射规则定义您要报告的指标或方法。以下是映射规则示例:

映射规则

这个规则表示,任何以 / 开头的 GET 请求都将按 1 增加指标 命中。此规则将与您的 API 的任何请求匹配。但最有可能会修改这个规则,因为它比较通用,而且在添加更多规则时通常会加倍计数。

Echo API 的以下规则显示更具体的示例:

Hello World 映射规则

1.2.1. 在产品和后端映射规则

映射规则在 API 产品和 API 后端级别上工作。在本节中,您将了解每个级别的映射规则的行为,并查看一个示例来描述映射规则如何运作。

在产品级别映射规则

  • 映射规则具有优先权。这意味着产品映射规则是第一个要评估的规则。
  • 映射规则始终被评估,并且独立于这些后端接收重定向的流量。

在后端级别上映射规则

  • 当您向后端添加映射规则时,这些规则将添加到所有产品中,并绑定所述后端。
  • 映射规则在产品级别上定义的映射规则后评估。
  • 只有在流量重定向到映射规则所属的同一后端时才评估映射规则。
  • 产品后端的路径会自动放在捆绑到上述产品的后端的每个映射规则的前面。

使用产品和后端映射规则示例

在本例中,我们从后端和产品开始。

/hello
/bye
  • Cool API 产品:

    • 具有这个公共端点:https://cool.api
    • 通过以下路由路径使用 Echo API 后端: /echo
  • 使用以下模式映射规则会自动成为 Cool API 产品的一部分:
/echo/hello
/echo/bye

现在,请考虑使用同一 Echo API 后端的名为 Tools for Devs 的额外产品。

1.2.2. 映射规则的匹配

映射规则的匹配由前缀执行,可以是任意复杂的。符号遵循 OpenAPI 和 ActiveDocs 规格:

  • 映射规则必须以正斜杠(/)开头。
  • 您可以在字面字符串的路径上执行匹配项(例如: /hello)。
  • 映射规则可以包含查询字符串或正文上的参数(例如: /{word}?value={value})。APIcast 获取参数的方式如下:

    • GET 方法:来自查询字符串。
    • POSTDELETEPUT 方法:来自正文。
  • 映射规则可以包含命名通配符(例如: /{word})。此规则将匹配占位符 {word} 中的任何内容,使请求(如 /morning )与规则匹配。通配符可以在斜杠或斜杠与点之间出现。参数也可以包含通配符。
  • 默认情况下,根据您指定的排序,从第一个到最后一个到最后一个映射规则评估所有映射规则。如果您添加规则 /v1 ,它将与路径以 /v1 开头的请求匹配(例如: /v1/word/v1/sentence)。
  • 您可以在模式的末尾添加一个美元符号($)来指定完全匹配项。例如,/v1/word$ 将仅匹配 /v1/word requests,并且不匹配 /v1/word/hello 请求。要完全匹配,还必须确保禁用了与所有(/)匹配的默认映射规则。
  • 多个映射规则可以匹配请求路径,但如果都不匹配,则会使用 HTTP 404 状态代码丢弃该请求。

1.2.3. 映射规则工作流

映射规则有以下工作流:

  • 您可以定义一个新的映射规则(请参阅 添加映射规则)。
  • 下一次重新加载时,映射规则会灰显,以防止意外修改。
  • 要编辑现有的映射规则,您必须首先通过单击右侧的铅笔图标启用它。
  • 若要删除规则,可单击回收站图标。
  • 当您提升 Integration > Configuration 中的更改时,所有修改和删除都会保存。

添加映射规则

要添加新映射规则,请执行以下步骤:

  1. Add Mapping Rule
  2. 指定以下设置:

    • 动词 :HTTP 请求动词(GETPOSTDEL E 或 PUT)。
    • Pattern :要匹配的模式(例如,/hello)。
    • 递增的指标或方法 :指标或方法名称。
    • 按 递增 :指标递增数字(例如 1)。
    • 最后? 如果此映射规则应被视为最后一个映射规则,以停止处理其他映射规则。
    • 位置 :指示映射规则执行位置的数字,对映射规则进行排序。
  3. 点击 Create Mapping Rule 以应用更改。

停止其他映射规则

要停止处理其他映射规则,您可以在创建新映射规则时选择 Last?。例如,如果您在 API Integration Settings 中定义以下映射规则,并且具有与每个规则关联的不同指标:

(get) /path/to/example/search
(get) /path/to/example/{id}

在使用 (get)/path/to/example/search 调用时,APIcast 会停止处理剩余的映射规则,并在规则匹配后递增其指标。

1.3. 主机标头

除非 Host 标头与预期匹配,否则仅将这些 API 产品需要此选项。在这些情况下,您的 API 产品前面的网关会导致问题,因为 主机 将是网关之一,例如 xxx-yyy.staging.apicast.io

为了避免这个问题,您可以在 Authentication Settings 中的 Host Header 字段中定义 API 产品需要的主机,托管 APIcast 实例将重写主机。

主机重写

1.4. 保护 API 后端

在生产环境中工作 APIcast 后,您可能想限制在没有凭证的情况下对 API 产品的直接访问。执行此操作的最简单方法是使用 APIcast 设置的 Secret Token。有关如何设置它的信息,请参阅高级 APIcast 配置

1.5. 将 APIcast 与私有 API 搭配使用

通过 APIcast,可以保护不能在互联网上公开访问的 API。必须满足的要求有:

  • 自我管理的 APIcast 必须用作部署选项。
  • APIcast 需要能够从公共互联网访问,并且能够向 3scale 服务管理 API 发出出站调用。
  • API 产品应该可由 APIcast 访问。

在这种情况下,您可以在 Private Base URL 字段中设置 API 的内部域名或 IP 地址,并像平常一样遵循其余步骤。但请注意,您无法利用 Staging 环境,测试调用将无法成功,因为登台 APIcast 实例由 3scale 托管,并且无法访问您的私有 API 后端。但是,在生产环境中部署 APIcast 后,如果配置正确,APIcast 将按预期工作。

1.6. 使用 OpenTracing 配置 APIcast

OpenTracing 是一种 API 规范和方法,用于配置文件和监控微服务。从版本 3.3 开始,APIcast 包括 OpenTracing Libraries 和 Jaeger Tracer 库

1.6.1. 先决条件

要在 APIcast 部署中添加分布式追踪,您需要确保以下先决条件:

  • 每个外部请求都应附加唯一的请求 ID,通常是通过 HTTP 标头连接。
  • 每个服务都应该将请求 ID 转发到其他服务。
  • 每个服务都应该在日志中输出请求 ID。
  • 每个服务均应记录其他信息,如请求的开始和结束时间。
  • 日志需要聚合,并提供通过 HTTP 请求 ID 解析的方式。

1.6.2. 流程

要配置 OpenTracing,请使用以下环境变量:

  • OPENTRACING_MERGER:定义要使用哪个 tracer 实现。目前,只有 Jaeger 可用。
  • OPENTRACING_CONFIG:要指定 tracer 的默认配置文件。您可以在此处看到一个 示例
  • OPENTRACING_HEADER_FORWARD:可选.您可以根据 OpenTracing 配置来设置此环境变量。

有关这些变量的更多信息,请参阅 APIcast 环境变量

要测试集成是否正常工作,您需要检查 Jaeger 追踪界面中是否报告 trace。

1.6.3. 附加信息

OpenTracing 和 Jaeger 集成在上游项目中找到 :https://github.com/3scale/apicast

1.6.4. 在 OpenShift 实例上安装 Jaeger

本节提供有关在运行的 OpenShift 实例上安装 Jaeger 的信息。

警告

Jaeger 是一个第三方组件,3scale 不提供支持,但 APIcast 的使用除外。以下说明仅作为参考示例提供,不适用于生产用途。

  1. 在当前命名空间中安装 Jaeger all-in-one:

    oc process -f https://raw.githubusercontent.com/jaegertracing/jaeger-openshift/master/all-in-one/jaeger-all-in-one-template.yml | oc create -f -
  2. 创建 Jaeger 配置文件 jaeger_config.json 并添加以下内容:

    {
        "service_name": "apicast",
        "disabled": false,
        "sampler": {
          "type": "const",
          "param": 1
        },
        "reporter": {
          "queueSize": 100,
          "bufferFlushInterval": 10,
          "logSpans": false,
          "localAgentHostPort": "jaeger-agent:6831"
        },
        "headers": {
          "jaegerDebugHeader": "debug-id",
          "jaegerBaggageHeader": "baggage",
          "TraceContextHeaderName": "uber-trace-id",
          "traceBaggageHeaderPrefix": "testctx-"
        },
        "baggage_restrictions": {
            "denyBaggageOnInitializationFailure": false,
            "hostPort": "127.0.0.1:5778",
            "refreshInterval": 60
        }
     }
    • 设置 1 的样本常数以对所有请求进行抽样
    • 设置 报告器的位置和队列大小
    • 设置标头,包括我们将用来跟踪请求的 TraceContextHeaderName
  3. 从 Jaeger 配置文件创建 ConfigMap,并将其挂载到 APIcast 中:

    oc create configmap jaeger-config --from-file=jaeger_config.json
    oc volume dc/apicast --add -m /tmp/jaeger/ --configmap-name jaeger-config
  4. 使用刚添加的配置启用 OpenTracing 和 Jaeger:

    oc set env deploymentConfig/apicast OPENTRACING_TRACER=jaeger OPENTRACING_CONFIG=/tmp/jaeger/jaeger_config.json
  5. 查找运行 Jaeger 接口的 URL:

    oc get route
    (…) jaeger-query-myproject.127.0.0.1.nip.io
  6. 打开上一步中的 Jaeger 接口,它显示来自 Openshift Health 检查的数据。
  7. 最后一步是将 OpenTracing 和 Jaeger 支持添加到您的后端 API,以便您可以查看完整的请求追踪。根据所用的框架和语言,每个后端都有所不同。作为参考示例,您可以使用 OpenTracing 与 Jaeger 来收集 Kubernetes 中的应用指标

有关配置 Jaeger 的更多信息,请参阅:

第 2 章 操作 Docker 容器化环境

2.1. 对 Docker 容器化环境的 APIcast 进行故障排除

本节介绍了在 Docker 容器化环境中使用 APIcast 时最常发现的问题。

2.1.1. 无法连接到 Docker 守护进程错误

docker:无法连接到 Docker 守护进程。Is the docker daemon running on this host? 错误消息可能是 Docker 服务尚未启动。您可以通过运行 sudo systemctl status docker.service 命令来检查 Docker 守护进程的状态。

确保您以 root 用户身份运行此命令,因为 Docker 容器化环境默认需要在 RHEL 中具有 root 权限。有关详细信息,请参阅 此处

2.1.2. 基本 Docker 命令行界面命令

如果您以分离模式启动容器(-d 选项),并希望检查正在运行的 APIcast 实例的日志,您可以使用 log 命令: sudo docker logs <container>。其中,<container> 是容器名称(上例中的 "apicast")或容器 ID。您可以使用 sudo docker ps 命令获取正在运行的容器及其 ID 和名称的列表。

要停止容器,请运行 sudo docker stop <container> 命令。您还可以运行 sudo docker rm <container> 命令删除容器。

有关可用命令的更多信息,请参阅 Docker 命令参考

第 3 章 高级 APIcast 配置

本节介绍 3scale 在暂存环境中的 API 网关的高级设置选项。

3.1. 定义 secret 令牌

出于安全考虑,从 3scale 网关到 API 后端的任何请求都包含名为 X-3scale-proxy-secret-token 的标头。您可以在 Integration 页面的 Authentication Settings 中设置此标头的值。

代理 secret 令牌

将 secret 令牌设置为代理和 API 之间的共享机密,以便您可以阻断所有来自网关的 API 请求(如果不希望它们)。当您使用沙盒网关设置流量管理策略时,这会添加额外的安全层来保护您的公共端点。

您的 API 后端必须具有公共可解析域才能使网关正常工作,因此知道您的 API 后端的任何人都可以绕过凭证检查。这不应该成为问题,因为暂存环境中的 API 网关并不适用于生产环境,但始终最好有一个可用的隔离。

3.2. 凭证

3scale 中的 API 凭证是 user_keyapp_id/app_key,具体取决于您使用的身份验证模式。OpenID Connect 对暂存环境中的 API 网关有效,但它无法在 Integration 页面中进行测试。

但是,您可能想要在 API 中使用不同的凭证名称。在这种情况下,如果使用 API 密钥模式,您需要为 user_key 设置自定义名称:

自定义 user_key

另外,对于 app_idapp_key

自定义 app_key/app_id

例如,如果这更适合您的 API,您可以将 app_id 重命名为 key。网关将使用名称 key,并将其转换为 app_id,然后向 3scale 后端执行授权调用。请注意,新凭证名称必须是字母数字。

您可以决定您的 API 是否在查询字符串(或者正文(如果不是 GET)或标头中传递凭证。

代理凭证位置
注意

APIcast 在提取凭据时规范化标头名称。这意味着它们不区分大小写,下划线和连字符可以平等对待。例如,如果您将 App Key 参数设置为 App_Key,其他值(如 app-key) 也被接受,作为有效的 app 键标头。

3.3. 配置错误消息

本节论述了如何配置 APIcast 错误消息。

作为代理,3scale APIcast 使用以下方法管理请求:

  • 如果没有错误,APIcast 会将请求从客户端传递到 API 后端服务器,并将 API 响应返回给客户端,无需修改。如果要修改响应,您可以使用 Header Modification 策略
  • 如果 API 响应错误消息,如 404 Not Found400 Bad Request,APIcast 将返回消息到客户端。但是,如果 APIcast 检测到其他错误,如 身份验证缺失,APIcast 会发送错误消息并终止请求。

因此,您可以将这些错误消息配置为由 APIcast 返回:

  • 身份验证失败:这个错误表示 API 请求不包含有效的凭证,无论是由于虚拟凭证还是临时暂停应用程序。另外,这个错误会在指标被禁用时生成,表示其值为 0
  • 身份验证缺失: 每当 API 请求不包含任何凭证时,都会生成这个错误。当用户没有将其凭证添加到 API 请求时会出现这种情况。
  • no match:这个错误表示请求与任何映射规则不匹配,因此没有更新指标。这不一定是错误,但意味着用户正在尝试随机路径,或者您的映射规则无法涵盖合法情况。
  • usage limit exceeded:这个错误表示客户端达到请求的端点的速率限制。如果请求与多个映射规则匹配,客户端可能会达到多个速率限制。

要配置错误,请按照以下步骤执行:

  1. [Your_product_name] > Integration > Settings
  2. Gateway response 下,选择您要配置的错误类型。
  3. 为这些字段指定值:

    • 响应代码:三位 HTTP 响应代码。
    • content-type: Content-Type 标头的值。
    • response Body:响应消息正文的值。
  4. 要保存您的更改,请点击 Update Product

3.4. 配置历史记录

每次单击 Promote v.[n] to Staging APIcast 时,其中 [n] 代表版本号,当前配置保存在 JSON 文件中。暂存网关将利用每个新请求拉取最新的配置。对于每个环境、暂存或生产环境,您可以看到所有之前配置文件的历史记录:

  1. [Your_product_name] > Integration > Configuration
  2. 点击您感兴趣的环境旁边的 Configuration history 链接: Staging APIcastProduction APIcast

请注意,无法自动回滚到以前的版本。相反,您可以访问所有配置版本的历史记录及其关联的 JSON 文件。使用这些文件来检查您在任何时间点上部署的配置。如果需要,可以手动重新创建任何部署。

3.5. 调试

设置网关配置很容易,但您可能仍会遇到错误。在这种情况下,网关可以返回有用的调试信息来跟踪错误。

要从 APIcast 获取调试信息,您必须将以下标头添加到 API 请求中: X-3scale-debug: {SERVICE_TOKEN},其服务帐户令牌与您要访问的 API 服务对应的服务令牌对应。

当找到标头且服务令牌有效时,网关会将以下信息添加到响应标头中:

X-3scale-matched-rules: /v1/word/{word}.json, /v1
X-3scale-credentials: app_key=APP_KEY&app_id=APP_ID
X-3scale-usage: usage%5Bversion_1%5D=1&usage%5Bword%5D=1

X-3scale-matched-rules 表示在用逗号分开的列表中为请求匹配了哪些映射规则。

标头 X-3scale-credentials 返回传递给 3scale 后端的凭证。

x-3scale-usage 表示报告到 3scale 后端的使用情况。usage%5Bversion_1%5D=1&usage%5Bword%5D=1 是一个 URL 编码的 usage[version_1]=1&usage[word]=1,显示 API 请求递增方法(metrics) version_1,并按 1 按 单词

3.6. 路径路由

如果配置了 APICAST_SERVICES_LIST 环境变量,APIcast 处理 3scale 帐户上配置的所有 API 服务(或服务子集)。通常,APIcast 会根据请求的主机名将 API 请求路由到适当的 API 服务,方法是将它与 公共基础 URL 匹配。找到匹配项的第一个服务用于授权。

路径路由功能允许在多个服务上使用相同的 公共基础 URL,并使用请求的路径路由请求。要启用该功能,请将 APICAST_PATH_ROUTING 环境变量设置为 true1。启用后,APIcast 将根据主机名和路径将传入的请求映射到服务。

如果要使用同一 公共基本 URL 通过不同的网关公开托管的多个后端服务,可使用此功能。要达到此目的,您可以为每个 API 后端(即 私有基本 URL)配置多个 API 服务并启用路径路由功能。

例如,您使用以下方式配置了 3 个服务:

  • Service A Public Base URL: api.example.com 映射规则: /a
  • Service B Public Base URL: api2.example.com 映射规则: /b
  • Service C Public Base URL: api.example.com 映射规则: /c

如果路径路由为 disabled (APICAST_PATH_ROUTING=false),对 api.example.com 的所有调用都将尝试匹配 Service A。因此,调用 api.example.com/capi.example.com/b 将失败,并显示 "No Mapping Rule match" 错误。

如果路径路由为 enabled (APICAST_PATH_ROUTING=true),则调用将由主机和路径匹配。因此:

  • api.example.com/a 将路由到 Service A
  • api.example.com/c 将路由到 Service C
  • api.example.com/b 将失败,显示"No Mapping Rule match"错误,即它不匹配 Service B,因为 公共基础 URL 不匹配。

如果使用路径路由,您必须确保使用相同 公共基本 URL 的不同服务中的映射规则之间没有冲突,例如,仅在一个服务中使用方法 + 路径模式的组合。

第 4 章 APIcast 策略

APIcast 策略是修改 APIcast 操作方式的功能单元。可以启用、禁用和配置策略,以控制它们如何修改 APIcast。使用策略添加默认 APIcast 部署中不可用的功能。您可以创建自己的策略,或使用 Red Hat 3scale 提供的标准策略

以下主题提供有关标准 APIcast 策略的信息,创建您自己的自定义 APIcast 策略并创建策略链。

使用策略链控制服务策略。策略链执行以下操作:

  • 指定 APIcast 使用的策略
  • 为策略 3scale 提供配置信息
  • 指定 3scale 加载策略的顺序
注意

红帽 3scale 提供了一种添加自定义策略的方法,但不支持自定义策略。

要使用自定义策略修改 APIcast 的行为,您必须执行以下操作:

  • 在 APIcast 中添加自定义策略
  • 定义配置 APIcast 策略的策略链
  • 将策略链添加到 APIcast

4.1. APIcast 标准策略

3scale 提供以下标准策略:

您可以在 3scale 中 启用和配置 标准策略。

4.1.1. 3scale Auth 缓存

3scale 身份验证缓存策略会缓存对 APIcast 发出的身份验证调用。您可以选择操作模式来配置缓存操作。

3scale Auth 缓存在以下模式中可用:

1.Strict - Cache only authorized calls.

"strict"模式仅缓存授权的调用。如果策略在"strict"模式下运行,并且调用失败或被拒绝,策略会使缓存条目失效。如果后端无法访问,则所有缓存的调用都会被拒绝,无论它们缓存的状态如何。

2.Resilient – Authorize according to last request when backend is down.

"弹性"模式会缓存授权和拒绝调用。如果策略在"弹性"模式下运行,则失败的调用不会使现有的缓存条目无效。如果后端变得不可访问,则命中缓存的调用仍会根据缓存的状态继续获得授权或拒绝。

3.Allow - When backend is down, allow everything unless seen before and denied.

"Allow"模式会缓存授权和被拒绝的调用。如果策略在"allow"模式下运行,则缓存的调用根据缓存的状态继续被拒绝或允许。但是,任何新调用都将缓存为授权。

重要

在"允许"模式下操作存在安全隐患。在使用"allow"模式时,请考虑以上问题并进行练习。

4.none - 禁用缓存。

"None"模式禁用缓存。如果您希望策略保持活动状态,但不想使用缓存,则此模式非常有用。

配置属性

属性描述必需?

caching_type

caching_type 属性允许您定义缓存将在其中操作的模式。

数据类型:枚举的字符串 [resilient, strict, allow, none]

策略对象示例

{
  "name": "caching",
  "version": "builtin",
  "configuration": {
    "caching_type": "allow"
  }
}

有关如何配置策略的详情,请参考文档中的创建策略链 部分。

4.1.2. 3scale Batcher

3scale Batcher 策略提供了标准的 APIcast 授权机制的替代方案,其中为 APIcast 接收的每个 API 请求调用 3scale 后端(Service Management API)。

3scale Batcher 策略会缓存授权状态和批处理使用报告,从而显著减少请求数到 3scale 后端。借助 3scale 批处理器策略,您可以通过降低延迟并提高吞吐量来提高 APIcast 性能。

当 3scale Batcher 策略被启用时,APIcast 会使用以下授权流:

  1. 在每个请求中,策略检查是否缓存凭证:

    • 如果缓存了凭据,策略将使用缓存的授权状态,而不是调用 3scale 后端。
    • 如果没有缓存凭据,策略会调用后端,并使用可配置的生存时间(TTL)来缓存授权状态。
  2. 策略不立即向 3scale 后端报告与请求对应的使用量,而是累计使用计数器将它们报告到批处理中的后端。单独的线程在单个调用中报告 3scale 后端的总用量计数器,具有可配置的频率。

3scale Batcher 策略提高了吞吐量,但准确性较低。使用限制和当前利用率存储在 3scale 中,APIcast 只能在向 3scale 后端发出调用时获取正确的授权状态。启用 3scale Batcher 策略时,在一个时间段内 APIcast 不会发送调用到 3scale。在这个时间窗内,发出调用的应用可能会超过定义的限值。

如果吞吐量比速率限制的准确性更重要,则将此策略用于高负载 API。当报告频率和授权 TTL 低于速率限制周期时,3scale Batcher 策略可以带来更好的准确性。例如,如果限制是每天的,并且报告频率和授权 TTL 被配置为几分钟。

3scale Batcher 策略支持以下配置设置:

  • auths_ttl :当授权缓存过期时,以秒为单位设置 TTL。

    当缓存当前调用的授权时,APIcast 将使用缓存的值。在 auths_ttl 参数中设置的时间后,APIcast 会移除缓存并调用 3scale 后端来检索授权状态。

  • batch_report_seconds :设置批处理报告的频率发送到 3scale 后端。默认值为 10 秒。
重要

要使用此策略,请在策略链中同时启用 3scale APIcast3scale 批处理器策略

4.1.3. 3scale Referrer

3scale 推荐器策略启用了 推荐过滤器功能。当服务策略链中启用策略时,APIcast 将 3scale Referencerer 策略的值发送到 Service Management API,作为向上方 AuthRep 调用。3scale Referencerer 策略的值在调用中的 referrer 参数中发送。

有关 Referrer Filtering 如何工作的更多信息,请参阅身份验证模式下的 Referrer Filtering 部分。

4.1.4. Anonymous Access(匿名访问)

匿名访问策略会公开一项服务,无需身份验证。例如,这对无法适应发送身份验证参数的传统应用程序很有用。匿名策略只支持使用 API Key 和 App Id / App Key 身份验证选项的服务。当为未提供任何凭证的 API 请求启用策略时,APIcast 将授权调用使用策略中配置的默认凭据。若要授权 API 调用,配置有凭据的应用必须存在并且处于活动状态。

使用 Application Plans,您可以配置用于默认凭证的应用程序的速率限值。

注意

在策略链中同时使用这些策略时,您需要将匿名访问策略放在 APIcast 策略的前面。

以下是策略所需的配置属性:

  • auth_type :从以下备选之一选择一个值,并确保属性与为 API 配置的身份验证选项对应:

    • app_id_and_app_key :用于 App ID / App Key 身份验证选项。
    • user_key: 用于 API 密钥身份验证选项。
  • app_id (仅适用于 app_id_and_app_key auth 类型):如果没有通过 API 调用提供凭证,则将用于授权的应用程序 Id。
  • app_key (仅适用于 app_id_and_app_key auth 类型):如果没有通过 API 调用提供凭据,则应用程序的 App Key 用于授权。
  • user_key (仅适用于 user_key auth_type):如果没有通过 API 调用提供凭据,应用程序使用的 API 密钥将用于授权。

图 4.1. 匿名访问策略

匿名访问策略

4.1.5. 条件策略

条件策略与其他 APIcast 策略不同,因为它包含一系列策略。它定义在每个 nginx 阶段 评估的条件,如 访问重写日志 等。当条件为 true 时,条件策略会为其链中包含的每个策略运行该阶段。

重要

APIcast Conditional Policy 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

以下示例假定 Conditional Policy 定义以下条件: 请求方法为 POST

APIcast --> Caching --> Conditional --> Upstream

                             |
                             v

                          Headers

                             |
                             v

                       URL Rewriting

在这种情况下,当请求是 POST 时,每个阶段的执行顺序如下:

  1. APIcast
  2. Caching
  3. Headers
  4. URL Rewriting
  5. Upstream

如果没有 POST 请求,每个阶段的执行顺序如下:

  1. APIcast
  2. Caching
  3. Upstream

4.1.5.1. 条件

确定在 Conditional Policy 链中运行的策略是否可以使用 JSON 表达或使用 liquid 模板。

本例检查请求路径是否为 /example_path

{
  "left": "{{ uri }}",
  "left_type": "liquid",
  "op": "==",
  "right": "/example_path",
  "right_type": "plain"
}

左和右边的运算对象都可以评估为 liquid 或纯字符串。纯文本字符串是默认值。

您可以将操作与 andor 组合使用。此配置检查与上例相同,外加 Backend 标头值:

{
  "operations": [
    {
      "left": "{{ uri }}",
      "left_type": "liquid",
      "op": "==",
      "right": "/example_path",
      "right_type": "plain"
    },
    {
      "left": "{{ headers['Backend'] }}",
      "left_type": "liquid",
      "op": "==",
      "right": "test_upstream",
      "right_type": "plain"
    }
  ],
  "combine_op": "and"
}

如需了解更多详细信息,请参阅 策略配置模式

4.1.5.1.1. liquid 支持的变量
  • uri
  • 主机
  • remote_addr
  • headers['Some-Header']

更新的变量列表可在此处找到: ngx_variable.lua

这个示例在请求的 Backend 标头是 staging 时执行上游策略:

{
   "name":"conditional",
   "version":"builtin",
   "configuration":{
      "condition":{
         "operations":[
            {
               "left":"{{ headers['Backend'] }}",
               "left_type":"liquid",
               "op":"==",
               "right":"staging"
            }
         ]
      },
      "policy_chain":[
         {
            "name":"upstream",
            "version": "builtin",
            "configuration":{
               "rules":[
                  {
                     "regex":"/",
                     "url":"http://my_staging_environment"
                  }
               ]
            }
         }
      ]
   }
}

4.1.6. CORS 请求处理

通过允许您指定以下指定来控制 CORS 行为,可通过交叉资源共享(CORS)请求处理策略来控制 CORS:

  • 允许的标头
  • 允许的方法
  • 允许的凭证
  • 允许的源标头

CORS 请求处理策略将阻止所有未指定的 CORS 请求。

注意

当在策略链中使用这两个策略时,您需要将 CORS Request 处理策略放在 APIcast 策略的前面。

配置属性

属性描述必需?

allow_headers

allow_headers 属性是一个数组,您可以在其中指定允许哪些 CORS 标头。

data type:字符串数组,必须是 CORS 标头

allow_methods

allow_methods 属性是一个数组,您可以在其中指定 APIcast 允许的 CORS 方法。

data type:枚举字符串的数组 [GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, CONNECT]

allow_origin

allow_origin 属性允许您指定原始域 APIcast 允许

数据类型:字符串

allow_credentials

allow_credentials 属性允许您指定 APIcast 是否允许带有凭证的 CORS 请求

数据类型:布尔值

策略对象示例

{
  "name": "cors",
  "version": "builtin",
  "configuration": {
    "allow_headers": [
      "App-Id", "App-Key",
      "Content-Type", "Accept"
    ],
    "allow_credentials": true,
    "allow_methods": [
      "GET", "POST"
    ],
    "allow_origin": "https://example.com"
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.7. Echo

Echo 策略将传入请求打印回客户端,以及可选的 HTTP 状态代码。

配置属性

属性描述必需?

status

Echo 策略将返回到客户端的 HTTP 状态代码

数据类型:整数

exit

指定 Echo 策略将使用的退出模式。request 退出模式将停止处理传入请求。set exit 模式跳过重写阶段。

data type:枚举字符串 [request, set]

策略对象示例

{
  "name": "echo",
  "version": "builtin",
  "configuration": {
    "status": 404,
    "exit": "request"
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.8. 边缘限制

Edge Limiting 策略旨在为发送到后端 API 的流量提供灵活的速率限制,并可与默认的 3scale 授权一起使用。策略支持的用例的一些示例包括:

  • 最终用户速率限制: Rate limits by the "sub"(subject)声明在请求的 Authorization 标头中传递的 JWT 令牌的值(配置为 {{ jwt.sub }})。
  • 请求每秒(RPS)速率限制.
  • 每个服务的全球速率限值:每个服务应用限制而不是每个应用程序。
  • 并发连接限制:设置允许的并发连接数。

4.1.8.1. 限制类型

该策略支持 lua-resty-limit-traffic 库提供的以下类型的限制:

  • leaky_bucket_limiters :基于基于基于平均请求数和最大突发大小的"leaky_bucket"算法。
  • fixed_window_limiters: 基于固定的时间窗口(最后 X 秒)。
  • connection_limiters :基于并发连接数。

您可以通过服务或全局限制来限制任何限制。

4.1.8.2. 限制定义

限制具有一个键,用于对用来定义限制(IP、服务、端点、ID、特定标头等)的实体进行编码。Key 在限制者的 key 参数中指定。

key 是由以下属性定义的对象:

  • 名称 :它是密钥的名称。它在范围内必须是唯一的。
  • Scope :它定义密钥的范围。支持的范围有:

    • 每个影响一个服务(service)的服务范围。
    • 影响所有服务(global)的全局范围。
  • name_type: 它定义如何评估"name"值:

    • 纯文本(plain
    • Liquid(liquid

每个限制也有一些参数因类型而异:

  • leaky_bucket_limiters: rate, burst.

    • 速率 :它定义每秒可进行的请求数量,而没有延迟。
    • burst :它定义每秒可以超过允许的速率的请求数。对于超过允许率(根据速率指定)的请求引入人工延迟。在超过 burst 中定义的每秒请求数后,请求将被拒绝。
  • fixed_window_limiters:count,window.计数 定义了在 窗口 中定义的每秒数发出的请求数量。
  • connection_limitersconnburstdelay.

    • conn :定义允许的最大并发连接数。它允许通过每秒 burst 连接超过该数量。
    • delay :这是延迟超过限制的连接的秒数。

例子

  1. 每分钟允许 10 个请求到 service_A:

    {
      "key": { "name": "service_A" },
      "count": 10,
      "window": 60
    }
  2. 允许延迟 1 到 10 的 100 个连接,延迟为 10:

    {
      "key": { "name": "service_A" },
      "conn": 100,
      "burst": 10,
      "delay": 1
    }

您可以为每个服务定义多个限制。如果定义了多个限制,则在至少达到一个限值时请求可以被拒绝或延迟。

4.1.8.3. 移动模板

Edge Limiting 策略允许通过在键中支持 Liquid 变量来指定动态密钥的限制。为此,键的 name_type 参数必须设置为 "liquid",而 name 参数则可使用 Liquid 变量。示例:{ { remote_addr }} 用于客户端 IP 地址,或者 {{ jwt.sub }} 用于 JWT 令牌的"sub"声明。

例如:

{
  "key": { "name": "{{ jwt.sub }}", "name_type": "liquid" },
  "count": 10,
  "window": 60
}

有关 Liquid 支持的详情请参考 第 5.1 节 “在策略中使用变量和过滤器”

4.1.8.4. 应用条件

该条件定义 API 网关何时应用限制器。您必须在每个限制器的 condition 属性中至少指定一个操作。

condition 由以下属性定义:

  • combined_op :应用于操作列表的布尔值运算符。支持 orand
  • 操作 :需要评估的条件列表。每个操作都由一个具有以下属性的对象表示:

    • left :操作的左侧。
    • left_type :如何评估 属性(解释或静止)。
    • 正确 :操作的正确部分。
    • right_type :如何评估 正确的 属性(解释或查询)。
    • op :在左侧和右部分之间应用的 Operator。支持以下两个值: == (等于)和 != (不等于)。

例如:

"condition": {
  "combine_op": "and",
  "operations": [
    {
      "op": "==",
      "right": "GET",
      "left_type": "liquid",
      "left": "{{ http_method }}",
      "right_type": "plain"
    }
  ]
}

4.1.8.5. 配置存储

默认情况下,Edge 限制策略将 OpenResty 共享字典用于速率限制计数器。但是,可以使用外部 Redis 服务器而不是共享字典。这在使用多个 APIcast 实例时很有用。Redis 服务器可以使用 redis_url 参数进行配置。

4.1.8.6. 错误处理

限制器支持以下参数来配置错误的处理方式:

  • limits_exceeded_error :允许配置在超过配置的限制时将返回到客户端的错误状态代码和消息。应配置以下参数:

    • status_code :超过限制时请求的状态代码。默认: 429
    • error_handling: 指定如何使用以下选项处理错误:

      • 退出 :停止处理请求并返回错误消息。
      • 日志 :完成处理请求并返回输出日志。
  • configuration_error :允许配置在配置不正确时返回到客户端的错误状态代码和消息。应配置以下参数:

    • status_code :配置问题时的状态代码。默认: 500
    • error_handling: 指定如何使用以下选项处理错误:

      • 退出 :停止处理请求并返回错误消息。
      • 日志 :完成处理请求并返回输出日志。

4.1.9. 标头修改

标头修改策略允许您修改现有标头,或者定义额外的标头以添加到或从传入的请求或响应中删除。您可以修改响应和请求标头。

Header 修改策略支持以下配置参数:

  • request: 应用到请求标头的操作列表
  • 响应 :应用到响应标头的操作列表

每个操作都由以下参数组成:

  • op :指定要应用的操作。add 操作会为现有标头添加一个值。这个 set 操作会创建一个标头和值,如果已存在该标头的值,则会覆盖现有的标头值。push 操作会创建一个标头和值,但如果已存在,则不会覆盖现有的标头值。相反,push 会将值添加到现有标头中。delete 操作会删除标头。
  • 标题 :指定要创建的标头或修改,并且可以用作标头名称(如 Custom-Header)的任何字符串。
  • value_type :定义如何评估标题值,可以是 纯文本 的纯文本或作为 Liquid 模板进行评估。更多信息请参阅 第 5.1 节 “在策略中使用变量和过滤器”
  • :指定将用于标头的值。对于值类型"liquid",值应当采用 {{ variable_from_context }} 格式。删除时不需要.

策略对象示例

{
  "name": "headers",
  "version": "builtin",
  "configuration": {
    "response": [
      {
        "op": "add",
        "header": "Custom-Header",
        "value_type": "plain",
        "value": "any-value"
      }
    ],
    "request": [
      {
        "op": "set",
        "header": "Authorization",
        "value_type": "plain",
        "value": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
      },
      {
        "op": "set",
        "header": "Service-ID",
        "value_type": "liquid",
        "value": "{{service.id}}"
      }
    ]
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.10. IP 检查

IP 检查策略用于根据 IP 列表拒绝或允许请求。

配置属性

属性描述数据类型必需?

check_type

check_type 属性有两个可能的值,即 白名单黑名单黑名单 将拒绝来自 IP 的所有请求。白名单 将拒绝来自列表中 IP 的所有请求。

字符串,必须是 whitelistblacklist

ips

ips 属性允许您指定 IP 地址列表以列入白名单或黑名单。可以使用单一 IP 和 CIDR 范围。

字符串数组,必须是有效的 IP 地址

error_msg

error_msg 属性允许您配置在请求被拒绝时返回的错误消息。

字符串

client_ip_sources

client_ip_sources 属性允许您配置如何检索客户端 IP。默认情况下使用最后一个调用者 IP。其他选项有 X-Forwarded-ForX-Real-IP

字符串数组,有效选项为 X-Forwarded-For, X-Real-IP, last_caller

策略对象示例

{
  "name": "ip_check",
  "configuration": {
    "ips": [ "3.4.5.6", "1.2.3.0/4" ],
    "check_type": "blacklist",
    "client_ip_sources": ["X-Forwarded-For", "X-Real-IP", "last_caller"],
    "error_msg": "A custom error message"
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.11. JWT 申索检查

JWT 声明基于 JSON Web Token(JWT)声明,您可以通过定义新规则来阻止资源目标和方法。

4.1.11.1. 关于 JWT 申索检查策略

为了基于 JWT 声明的值进行路由,您需要链中的策略验证 JWT,并将声明存储在策略共享的上下文中。

如果 JWT Claim Check 策略正在阻止资源和方法,该策略也会验证 JWT 操作。另外,如果方法资源不匹配,则请求将继续至后端 API。

示例:如果 GET 请求,如果不是请求,则 JWT 需要以 admin 身份具有角色声明。另一方面,任何非 GET 请求都不会验证 JWT 操作,因此允许 POST 资源而无需 JWT 约束。

{
  "name": "apicast.policy.jwt_claim_check",
  "configuration": {
      "error_message": "Invalid JWT check",
      "rules": [
          {
              "operations": [
                  {"op": "==", "jwt_claim": "role", "jwt_claim_type": "plain", "value": "admin"}
              ],
              "combine_op":"and",
              "methods": ["GET"],
              "resource": "/resource",
              "resource_type": "plain"
          }
      ]
  }
}

4.1.11.2. 在策略链中配置 JWT 声明检查策略

要在策略链中配置 JWT Claim Check 策略,请执行以下操作:

先决条件:

  • 您需要有权访问 3scale 安装。
  • 您需要等待所有部署完成。
4.1.11.2.1. 配置策略
  1. 要将 JWT Claim Check 策略添加到您的 API,请按照 启用标准策略中介绍的步骤操作, 然后选择 JWT Claim Check。
  2. 单击 JWT 声明检查 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 若要添加规则,可单击加号 + 图标。
  5. 指定 resource_type
  6. 选择 operator。
  7. 指明规则控制的资源
  8. 要添加允许的方法,请单击加号 + 图标。
  9. 键入错误消息,以便在流量被阻止时向用户显示。
  10. 使用 JWT Claim Check 设置完 API 后,单击 Update Policy

    • 单击对应部分中的加号 + 图标,您可以添加更多资源类型和允许的方法。
  11. 单击 Update Policy Chain 以保存您的更改。

4.1.12. Liquid Context Debug

注意

Liquid Context Debug 策略仅用于开发环境中而不是生产环境中的调试用途。

此策略使用 JSON 响应 API 请求,其中包含上下文中可用的对象和值,并可用于评估 Liquid 模板。与 3scale APIcast 或 上游策略结合使用时,必须将 Liquid Context Debug 放置在策略链中才能正常工作。为避免循环引用,该策略仅包含重复的对象,并将其替换为 stub 值。

启用策略时 APIcast 返回的值示例:

    {
      "jwt": {
        "azp": "972f7b4f",
        "iat": 1537538097,
        ...
        "exp": 1537574096,
        "typ": "Bearer"
      },
      "credentials": {
        "app_id": "972f7b4f"
      },
      "usage": {
        "deltas": {
          "hits": 1
        },
        "metrics": [
          "hits"
        ]
      },
      "service": {
        "id": "2",
        ...
      }
      ...
    }

4.1.13. 日志记录

Logging 策略有两个目的:

  • 启用和禁用访问日志输出:
  • 要为每个服务创建自定义访问日志格式,并能够设置编写自定义访问日志的条件:

您可以将 Logging 策略与访问日志位置的全局设置合并。设置 APICAST_ACCESS_LOG_FILE 环境变量,以配置 APIcast 访问日志的位置。默认情况下,此变量设置为 /dev/stdout,这是标准输出设备。有关全局 APIcast 参数的详情,请参考 ???

另外,日志记录策略具有以下功能:

  • 此策略仅支持 enable_access_logs 配置参数。
  • 要启用访问日志,请选择 enable_access_logs 参数或禁用 Logging 策略。
  • 为 API 禁用访问日志:

    1. 启用策略。
    2. 清除 enable_access_logs 参数
    3. 单击 Submit 按钮。
  • 默认情况下,策略链中不启用此策略。

4.1.13.1. 所有 API 的全局配置

日志记录选项有助于避免出现 API 中未正确格式化的日志问题。可以设置自定义 APIcast 环境变量,并且所有 API 都实施日志记录策略。以下是载入在所有服务中的策略示例: custom_env.lua

local cjson = require('cjson')
local PolicyChain = require('apicast.policy_chain')
local policy_chain = context.policy_chain

local logging_policy_config = cjson.decode([[
{
  "enable_access_logs": false,
  "custom_logging": "\"{{request}}\" to service {{service.id}} and {{service.name}}"
}
]])

policy_chain:insert( PolicyChain.load_policy('logging', 'builtin', logging_policy_config), 1)

return {
  policy_chain = policy_chain,
  port = { metrics = 9421 },
}

使用这个特定环境运行 APIcast:

docker run --name apicast --rm -p 8080:8080 \
    -v $(pwd):/config \
    -e APICAST_ENVIRONMENT=/config/custom_env.lua \
    -e THREESCALE_PORTAL_ENDPOINT=https://ACCESS_TOKEN@ADMIN_PORTAL_DOMAIN \
    quay.io/3scale/apicast:master

这些是要考虑的 Docker 命令的关键概念:

  • 当前 Lua 文件必须共享到容器 -v $(pwd):/config.
  • APICAST_ENVIRONMENT 变量必须设置为存储在 /config 目录中的 Lua 文件。

4.1.13.2. 例子

本节论述了使用日志记录策略的一些示例。这些示例考虑以下注意事项:

  • 如果启用了 custom_loggingenable_json_logs 属性,则会禁用默认访问日志。
  • 如果启用了 enable_json_logs,将省略 custom_logging 字段。

禁用访问日志

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false
  }
}

启用自定义访问日志

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false,
    "custom_logging": "[{{time_local}}] {{host}}:{{server_port}} {{remote_addr}}:{{remote_port}} \"{{request}}\" {{status}} {{body_bytes_sent}} ({{request_time}}) {{post_action_impact}}",
  }
}

使用服务标识符启用自定义访问日志

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false,
    "custom_logging": "\"{{request}}\" to service {{service.id}} and {{service.name}}",
  }
}

使用 JSON 格式配置访问日志

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false,
    "enable_json_logs": true,
    "json_object_config": [
      {
        "key": "host",
        "value": "{{host}}",
        "value_type": "liquid"
      },
      {
        "key": "time",
        "value": "{{time_local}}",
        "value_type": "liquid"
      },
      {
        "key": "custom",
        "value": "custom_method",
        "value_type": "plain"
      }
    ]
  }
}

仅为成功请求配置自定义访问日志

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false,
    "custom_logging": "\"{{request}}\" to service {{service.id}} and {{service.name}}",
    "condition": {
      "operations": [
        {"op": "==", "match": "{{status}}", "match_type": "liquid", "value": "200"}
      ],
      "combine_op": "and"
    }
  }
}

自定义访问日志,其中响应状态与 200500匹配

{
  "name": "apicast.policy.logging",
  "configuration": {
    "enable_access_logs": false,
    "custom_logging": "\"{{request}}\" to service {{service.id}} and {{service.name}}",
    "condition": {
      "operations": [
        {"op": "==", "match": "{{status}}", "match_type": "liquid", "value": "200"},
        {"op": "==", "match": "{{status}}", "match_type": "liquid", "value": "500"}
      ],
      "combine_op": "or"
    }
  }
}

4.1.13.3. 有关自定义日志记录的附加信息

对于自定义日志记录,您可以使用 Liquid 模板和导出的变量。这些变量包括:

  • NGINX default 指令变量:log_format.例如: {{remote_addr}}
  • 响应和请求标头:

    • {{req.headers.FOO}}: 要获取请求中的 FOO 标头。
    • {{res.headers.FOO}}: 要检索响应时的 FOO 标头。
  • 服务信息,如 {{service.id}},以及这些参数提供的所有服务属性:

    • THREESCALE_CONFIG_FILE
    • THREESCALE_PORTAL_ENDPOINT

4.1.14. 维护模式

Maintenance Mode 策略允许您使用指定状态代码和消息拒绝传入的请求。它对于维护期或临时阻止 API 非常有用。

配置属性

下表列出了可能的属性和默认值:

属性valuedefault描述

status

整数,可选

503

响应代码

message

字符串,可选

503 服务不可用 - 维护

响应消息

维护模式策略示例

{
  "policy_chain": [
    {"name": "maintenance-mode", "version": "1.0.0",
    "configuration": {"message": "Be back soon..", "status": 503} },
  ]
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.15. OAuth 2.0 通用 TLS 客户端身份验证

此策略为每个 API 调用执行 OAuth 2.0 通用 TLS 客户端身份验证。

OAuth 2.0 通用 TLS 客户端身份验证策略 JSON 示例如下所示:

{
  "$schema": "http://apicast.io/policy-v1/schema#manifest#",
  "name": "OAuth 2.0 Mutual TLS Client Authentication",
  "summary": "Configure OAuth 2.0 Mutual TLS Client Authentication.",
  "description": ["This policy executes OAuth 2.0 Mutual TLS Client Authentication ",
    "(https://tools.ietf.org/html/draft-ietf-oauth-mtls-12) for every API call."
  ],
  "version": "builtin",
  "configuration": {
    "type": "object",
    "properties": { }
  }
}

4.1.16. OAuth 2.0 令牌内省

OAuth 2.0 Token Introspection 策略允许使用令牌签发者(Red Hat Single Sign-On)的 Token Introtion Endpoint(Red Hat Single Sign-On)验证选项来验证用于通过 OpenID Connect(OIDC)身份验证选项的 JSON Web Token Token 令牌(JWT)令牌。

APIcast 支持 auth_type 字段中的以下身份验证类型,以确定 Token Introspection Endpoint 和调用此端点时使用的凭证 APIcast:

  • use_3scale_oidc_issuer_endpoint: APIcast 使用客户端凭证、客户端 ID 和客户端 Secret,以及来自 Service Integration 页面中配置的 OIDC 签发者设置的 Token Introspection Endpoint。APIcast 从 token_introspection_endpoint 字段发现 Token Introspection 端点。此字段位于 OIDC 签发者返回的 .well-known/openid-configuration 端点中。

例 4.1. 身份验证类型设置为 use_3scale_oidc_issuer_endpoint

"policy_chain": [
…​
  {
    "name": "apicast.policy.token_introspection",
    "configuration": {
      "auth_type": "use_3scale_oidc_issuer_endpoint"
    }
  }
…​
],
  • client_id+client_secret:此选项允许您指定不同的令牌内省端点,以及客户端 ID 和客户端 Secret APIcast 用来请求令牌信息。使用这个选项时,请设置以下配置参数:

    • client_id :为令牌内省端点设置客户端 ID。
    • client_secret :为令牌内省端点设置客户端 Secret。
    • introspection_url :设置 Introspection Endpoint URL。

例 4.2. 身份验证类型设置为 client_id+client_secret

"policy_chain": [
…​
  {
    "name": "apicast.policy.token_introspection",
    "configuration": {
      "auth_type": "client_id+client_secret",
      "client_id": "myclient",
      "client_secret": "mysecret",
      "introspection_url": "http://red_hat_single_sign-on/token/introspection"
    }
  }
…​
],

无论 auth_type 字段中的设置是什么,APIcast 使用 Basic Authentication 来授权 Token Introspection 调用(Authorization: Basic <token> 标头,其中 <token &gt ; 是 Base64 编码的 < client_id>:<client_secret&gt;)。

OAuth 2.0 令牌内省配置

Token Introspection Endpoint 的响应中包含 active 属性。APIcast 检查此属性的值。根据属性的值,APIcast 授权或拒绝调用:

  • true :调用已被授权
  • false: 调用被拒绝,且 Authentication Failed 错误

该策略允许缓存令牌,以避免在相同 JWT 令牌的每个调用中调用 Token Introspection Endpoint。要为 Token Introspection Policy 启用令牌缓存,请将 max_cached_tokens 字段设置为从 0 (禁用该功能)到 10000 直接的值。另外,您可以在 max_ttl_tokens 字段中将令牌的值从 1 设置为 3600 秒。

4.1.17. 代理服务

Proxy Service 策略允许用户定义 通过定义的代理发送流量的 HTTP 代理。

以下显示了流量流示例:

                 ,-------.          ,---------.          ,----------.
                 |APIcast|          |HTTPPROXY|          |APIBackend|
  User           `---+---'          `----+----'          `----------'
   |  GET /resource  |                   |                    |
   | --------------->|                   |                    |
   |                 |                   |                    |
   |                 |  Get /resource    |                    |
   |                 |------------------>|                    |
   |                 |                   |                    |
   |                 |                   |  Get /resource/    |
   |                 |                   | - - - - - - - - - >|
   |                 |                   |                    |
   |                 |                   |     response       |
   |                 |                   |<- - - - - - - - - -|
   |                 |                   |                    |
   |                 |     response      |                    |
   |                 |<------------------|                    |
   |                 |                   |                    |
   |                 |                   |                    |
   | <---------------|                   |                    |
  User           ,---+---.          ,----+----.          ,----------.
                 |APIcast|          |HTTPPROXY|          |APIBackend|
                 `-------'          `---------'          `----------'

到 3scale 后端的所有 APIcast 流量都不会使用代理,因此这只适用于该服务和 APIcast 和 API 后端之间的通信。

如果要通过 Proxy Service 策略使用所有流量,则必须使用 HTTP_PROXY 环境变量。

4.1.17.1. Configuration(配置)

以下示例显示了策略更改配置。

"policy_chain": [
    {
      "name": "apicast.policy.apicast"
    },
    {
      "name": "apicast.policy.http_proxy",
      "configuration": {
          "all_proxy": "http://192.168.15.103:8888/",
          "https_proxy": "https://192.168.15.103:8888/",
          "http_proxy": "https://192.168.15.103:8888/"
      }
    }
]

如果未定义 http_proxyhttps_proxy,则将执行 all_proxy

4.1.17.1.1. 注意事项
  • Proxy Service 策略将禁用所有负载平衡策略和流量将发送到代理。
  • 如果定义了 HTTP_PROXYHTTPS_PROXYALL_PROXY 参数,则策略将覆盖这些值。
  • 代理连接不支持身份验证。
4.1.17.1.2. 使用案例示例

Proxy Service 策略旨在使用 Apache Camel 应用更精细的策略和转换。

项目示例

请参阅 GitHub 上的 camel-netty-proxy 示例。此项目是一种 HTTP 代理,可将 API 后端提供的所有响应正文转换为大写。

4.1.18. Retry

重试策略将请求数设置为上游 API。重试策略是为每个服务配置的,因此用户可以根据需要为任意数量或任意数量的服务启用重试,并为不同的服务配置不同的重试值。

重要

从 3scale 2.8 起,无法配置从策略重试的情况。这通过环境变量 APICAST_UPSTREAM_RETRY_CASES 控制,后者将重试请求应用到所有服务。有关此内容,请查看 APICAST_UPSTREAM_RETRY_CASES

重试策略 JSON 的示例如下所示:

{
  "$schema": "http://apicast.io/policy-v1/schema#manifest#",
  "name": "Retry",
  "summary": "Allows retry requests to the upstream",
  "description": "Allows retry requests to the upstream",
  "version": "builtin",
  "configuration": {
    "type": "object",
    "properties": {
      "retries": {
        "description": "Number of retries",
        "type": "integer",
        "minimum": 1,
        "maximum": 10
      }
    }
  }
}

4.1.19. RH-SSO/Keycloak 角色检查

此策略在与 OpenID Connect 身份验证选项一起使用时添加角色检查。此策略验证红帽单点登录(RH-SSO)中发布的访问令牌中的域角色和客户端角色。当您要向 3scale 的每个客户端资源添加角色检查时,会指定 realm 角色。

有两种类型的角色检查策略配置中指定的 type 属性:

  • 白名单 (默认):当使用 白名单 时,APIcast 将检查 JWT 令牌中是否存在指定的范围,并在 JWT 中没有范围时拒绝调用。
  • blacklist :当使用 黑名单 时,如果 JWT 令牌包含黑名单范围,APIcast 将拒绝调用。

同一策略中无法同时配置 blacklistwhitelist 检查,但您可以在 APIcast 策略链中添加多个 RH-SSO/Keycloak 角色检查 策略链。

您可以通过策略配置的 scopes 属性配置范围列表。

每个 scope 对象具有以下属性:

  • 资源 :角色控制的资源(端点)。这个格式与映射规则相同。模式从字符串开头匹配,若要完全匹配,您必须在末尾附加 $
  • resource_type :这定义了 资源 值的评估方式。

    • 以纯文本(plain)形式:以纯文本形式评估 资源 值。示例: /api/v1/products$.
    • 作为 Liquid 文本(liquid):允许在 资源 值中使用 Liquid。示例: /resource_{{ jwt.aud }} 管理对包含客户端 ID 的资源的访问。
  • 方法 :使用此参数根据 RH-SSO 中的用户角色,列出 APIcast 中允许的 HTTP 方法。例如,您可以允许使用以下方法:

    • 用于访问 /resource1role1 realm 角色。对于没有此 realm 角色的方法,您需要指定 黑名单
    • client1 角色调用 role1 来访问 /resource1
    • 用于访问 /resource1role1role2 域角色。指定 realm_roles 中的角色。您还可以指定各个角色的范围。
    • 应用客户端的 role1 角色 (这是访问令牌的接收者)来访问 /resource1。使用 liquid 客户端类型向客户端指定 JSON Web Token(JWT)信息。
    • 客户端角色,包括应用客户端的客户端 ID(访问令牌的接收者)来访问 /resource1。使用 liquid 客户端类型,将 JWT 信息指定为客户端角色的 name
    • 名为 role1 的客户端角色,以访问资源,包括应用客户端 ID。使用 liquid 客户端类型为 resource 指定 JWT 信息。
  • realm_roles :使用它来检查 realm 角色(请参阅 Red Hat Single Sign-On 文档中的 Realm Roles )。

    域角色存在于红帽单点登录发布的 JWT 中。

      "realm_access": {
        "roles": [
          "<realm_role_A>", "<realm_role_B>"
        ]
      }

    策略中必须指定实际角色。

    "realm_roles": [
      { "name": "<realm_role_A>" }, { "name": "<realm_role_B>" }
    ]

    以下是 realm_roles 数组中每个对象的可用属性:

  • name :指定角色的名称。
  • name_type :定义必须如何评估名称;它可以是 的 或 liquid (与 resource_type的相同)。
  • client_roles :使用 client_roles 检查客户端命名空间中的特定访问角色(请参阅 Red Hat Single Sign-On 文档中的客户端角色 )。

    客户端角色存在于 JWT 中的 resource_access 声明下。

      "resource_access": {
        "<client_A>": {
          "roles": [
            "<client_role_A>", "<client_role_B>"
          ]
        },
        "<client_B>": {
          "roles": [
            "<client_role_A>", "<client_role_B>"
          ]
        }
      }

    指定策略中的客户端角色。

    "client_roles": [
      { "name": "<client_role_A>", "client": "<client_A>" },
      { "name": "<client_role_B>", "client": "<client_A>" },
      { "name": "<client_role_A>", "client": "<client_B>" },
      { "name": "<client_role_B>", "client": "<client_B>" }
    ]

    以下是 client_roles 数组中每个对象的可用属性:

  • name :指定角色的名称。
  • name_type :定义必须如何评估 name 值;它可以是 的 或 liquid (与 resource_type的相同)。
  • client :指定角色的客户端。如果未定义,此策略将 aud 声明用作客户端。
  • client_type :定义必须如何评估 客户端 值;它可以是 的或禁止(与 resource_type的作用相同)。

4.1.20. 路由

Routing 策略允许您将请求路由到不同的目标端点。您可以定义目标端点,然后将从 UI 传入的请求路由到使用正则表达式的请求。

与 APIcast 策略组合时,路由策略应放在链中的 APIcast 之前,因为首先将内容输出到响应的两个策略。当第二个进程获得更改以运行其内容阶段时,该请求已发送到客户端,因此不会输出到响应。

4.1.20.1. 路由规则

  • 如果存在多个规则,路由策略会应用第一个匹配项。您可以对这些规则进行排序。
  • 如果没有规则匹配,策略不会更改上游,并使用服务配置中定义的已定义的私有基本 URL。

4.1.20.2. 请求路径规则

这是当路径为 /accounts 时路由到 http://example.com 的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/accounts"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.3. 标头规则

这是当标头 Test-Header 的值为 123 时路由到 http://example.com 的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "header",
                "header_name": "Test-Header",
                "op": "==",
                "value": "123"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.4. 查询参数规则

这是当查询参数 test_query_arg123 时路由到 http://example.com 的配置 :

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "query_arg",
                "query_arg_name": "test_query_arg",
                "op": "==",
                "value": "123"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.5. JWT 声明规则

若要基于 JWT 声明的值进行路由,链中需要有一个策略来验证 JWT 并将其存储在策略共享的上下文中。

这是当 JWT 声明 test_claim 的值为 123 时路由到 http://example.com 的配置 :

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "jwt_claim",
                "jwt_claim_name": "test_claim",
                "op": "==",
                "value": "123"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.6. 多操作规则

规则可以有多个操作,只有当所有上游评估为 true 时(使用 'and' combine_op)或至少被评估为 true (使用 'or' combine_op)指向给定上游的操作。combine_op 的默认值为 'and'。

这是在请求的路径为 /accounts 以及标头 Test-Header 的值为 123 时路由到 http://example.com 的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "combine_op": "and",
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/accounts"
              },
              {
                "match": "header",
                "header_name": "Test-Header",
                "op": "==",
                "value": "123"
              }
            ]
          }
        }
      ]
    }
  }

这是在请求的路径为 /accounts 或者标头 Test-Header 的值为 123 时路由到 http://example.com 的配置 :

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "combine_op": "or",
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/accounts"
              },
              {
                "match": "header",
                "header_name": "Test-Header",
                "op": "==",
                "value": "123"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.7. 组合规则

规则可以组合在一起使用。当有多个规则时,上游选择是首批评估为 true 的规则之一。

这是包含多个规则的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://some_upstream.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/accounts"
              }
            ]
          }
        },
        {
          "url": "http://another_upstream.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/users"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.8. catch-all 规则

没有操作的规则始终匹配。这对于定义概括性规则非常有用。

如果路径为 /abc,则此配置将请求路由到 http://some_upstream.com,如果路径是 /def,将请求路由到 http://another_upstream.com,最后,如果之前的规则没有评估为 true,则会将请求路由到 http://default_upstream.com

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://some_upstream.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/abc"
              }
            ]
          }
        },
        {
          "url": "http://another_upstream.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/def"
              }
            ]
          }
        },
        {
          "url": "http://default_upstream.com",
          "condition": {
            "operations": []
          }
        }
      ]
    }
  }

4.1.20.9. 支持的操作

支持的操作有 ==, !=matches。后者将字符串与正则表达式匹配,并使用 ngx.re.match来实施

这是使用 != 的配置。当路径不是 /accounts 时,它会路由到 http://example.com:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "!=",
                "value": "/accounts"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.10. 移动模板

可以将弹性模板用于配置的值。如果链中的策略将键 my_var 存储在上下文中,则可以使用动态值定义规则。

这是使用该值路由请求的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "condition": {
            "operations": [
              {
                "match": "header",
                "header_name": "Test-Header",
                "op": "==",
                "value": "{{ my_var }}",
                "value_type": "liquid"
              }
            ]
          }
        }
      ]
    }
  }

4.1.20.11. 设置 host_header中使用的主机

默认情况下,当路由请求时,策略使用匹配的规则的 URL 主机设置 Host 标头。可以通过 host_header 属性指定不同的主机。

这是将 some_host.com 指定为 Host 标头主机的配置:

 {
    "name": "routing",
    "version": "builtin",
    "configuration": {
      "rules": [
        {
          "url": "http://example.com",
          "host_header": "some_host.com",
          "condition": {
            "operations": [
              {
                "match": "path",
                "op": "==",
                "value": "/"
              }
            ]
          }
        }
      ]
    }
  }

4.1.21. SOAP

SOAP 策略与 HTTP 请求的 SOAPActionContent-Type 标头中提供的 SOAP 操作 URI 匹配策略中指定的映射规则。

配置属性

属性描述必需?

pattern

pattern 属性允许您在 SOAPAction URI 中指定 APIcast 将寻找匹配项的字符串。

数据类型:字符串

metric_system_name

metric_system_name 属性允许您指定匹配模式将注册命中的 3scale 后端指标。

数据类型:字符串,必须是一个有效的 metric

策略对象示例

{
  "name": "soap",
  "version": "builtin",
  "configuration": {
    "mapping_rules": [
      {
        "pattern": "http://example.com/soap#request",
        "metric_system_name": "soap",
        "delta": 1
      }
    ]
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.22. TLS 客户端证书验证

借助 TLS 客户端证书验证策略,APIcast 实施 TLS 握手,并根据白名单验证客户端证书。白名单包含由认证机构(CA)或纯客户端证书签名的证书。如果证书过期或无效,请求将被拒绝,且不会处理其他策略。

客户端连接到 APIcast 以发送请求并提供客户端证书。APIcast 根据策略配置验证传入请求中提供的证书的真实性。APIcast 也可以配置为使用自己的客户端证书,以在连接到上游时使用它。

4.1.22.1. 设置 APIcast 以使用 TLS 客户端证书验证

APIcast 需要配置为终止 TLS。按照以下步骤配置用户在 APIcast 上提供的客户端证书验证策略。

先决条件:

  • 您需要有权访问 3scale 安装。
  • 您需要等待所有部署完成。
4.1.22.1.1. 设置 APIcast 以使用策略

要设置 APIcast 并将其配置为终止 TLS,请按照以下步骤操作:

  1. 您需要获取访问令牌并部署 APIcast 自我管理,如 使用 OpenShift 模板部署 APIcast 中所述

    注意

    需要 APIcast 自我管理的部署,因为 APIcast 实例需要重新配置,才能将一些证书用于整个网关。

  2. 仅用于测试目的,您可以使用没有缓存和暂存环境以及 --param 标志的 lazy 加载器来进行测试。

    oc new-app -f https://raw.githubusercontent.com/3scale/3scale-amp-openshift-templates/master/apicast-gateway/apicast.yml --param CONFIGURATION_LOADER=lazy --param DEPLOYMENT_ENVIRONMENT=staging --param CONFIGURATION_CACHE=0
  3. 生成证书用于测试目的。另外,对于生产部署,您可以使用证书颁发机构提供的证书。
  4. 使用 TLS 证书创建 Secret

    oc create secret tls apicast-tls
    --cert=ca/certs/server.crt
    --key=ca/keys/server.key
  5. 在 APIcast 部署中挂载 Secret

    oc set volume dc/apicast --add --name=certificates --mount-path=/var/run/secrets/apicast --secret-name=apicast-tls
  6. 将 APIcast 配置为为 HTTPS 开始侦听端口 8443

    oc set env dc/apicast APICAST_HTTPS_PORT=8443 APICAST_HTTPS_CERTIFICATE=/var/run/secrets/apicast/tls.crt APICAST_HTTPS_CERTIFICATE_KEY=/var/run/secrets/apicast/tls.key
  7. 在服务中公开 8443

    oc patch service apicast -p '{"spec":{"ports":[{"name":"https","port":8443,"protocol":"TCP"}]}}'
  8. 删除默认路由

    oc delete route api-apicast-staging
  9. apicast 服务作为路由公开

    oc create route passthrough --service=apicast --port=https --hostname=api-3scale-apicast-staging.$WILDCARD_DOMAIN
    注意

    您要使用的每个 API 和每个 API 的域更改都需要这一步。

  10. 通过在占位符中指定 [Your_user_key],验证之前部署的网关是否正常工作并且配置已保存。

    curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN?user_key=[Your_user_key] -v --cacert ca/certs/ca.crt

4.1.22.2. 在策略链中配置 TLS 客户端证书验证

要在策略链中配置 TLS 客户端证书验证,请执行以下操作:

先决条件

4.1.22.2.1. 配置策略
  1. 要将 TLS 客户端证书验证策略添加到您的 API,请按照 启用标准策略中介绍的步骤操作, 然后选择 TLS 客户端证书验证。
  2. 单击 TLS 客户端证书验证 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 若要添加证书到白名单,可单击加号 + 图标。
  5. 指定包括 -----BEGIN CERTIFICATE----------END CERTIFICATE----- 的证书。
  6. 使用 TLS 客户端证书验证设置完 API 后,单击 Update Policy

另外:

  • 您可以通过单击加号 + 图标来添加更多证书。
  • 您还可以通过单击上下箭头来重新组织证书。

要保存您的更改,请点击 Update Policy Chain

4.1.22.3. 验证 TLS 客户端证书验证策略的功能

要验证 TLS 客户端证书验证策略的功能,请执行以下操作:

先决条件:

4.1.22.3.1. 验证策略功能

您可以通过在占位符中指定 [Your_user_key] 来验证应用的策略。

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt --cert ca/certs/client.crt --key ca/keys/client.key

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt --cert ca/certs/server.crt --key ca/keys/server.key

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt

4.1.22.4. 从白名单中删除证书

要从白名单中删除证书,请执行以下操作:

先决条件

4.1.22.4.1. 删除证书
  1. 单击 TLS 客户端证书验证 链接。
  2. 要从白名单中删除证书,请点击 x 图标。
  3. 删除证书后,点击 Update Policy

要保存您的更改,请点击 Update Policy Chain

4.1.22.5. 参考材料

有关使用证书的更多信息,请参阅 红帽认证系统

4.1.23. TLS 终止

本节提供有关传输层安全(TLS)终止策略的信息:从策略中移除概念、配置、验证和文件删除。

借助 TLS Termination 策略,您可以将 APIcast 配置为为每个 API 完成 TLS 请求,而无需为所有 API 使用单个证书。APIcast 在建立与客户端的连接前拉取配置设置;因此,APIcast 使用策略中的证书,并使 TLS 终止。此策略可与以下源配合工作:

  • 存储在策略配置中。
  • 存储在文件系统中。

默认情况下,策略链中不启用此策略。

4.1.23.1. 在策略链中配置 TLS 终止

本节介绍了在策略链中配置 TLS 终止的先决条件和步骤,以及增强保密邮件(PEM)格式的证书。

先决条件

  • 用户签发的证书
  • PEM 格式的服务器证书
  • PEM 格式的证书私钥
4.1.23.1.1. 配置策略
  1. 要将 TLS 终止策略添加到您的 API 中,请按照 启用标准策略 中所述的步骤操作,然后选择 TLS 终止。
  2. 单击 TLS 终止 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 若要将 TLS 证书添加到策略,可单击加号 + 图标。
  5. 选择证书源:

    • 嵌入式证书:指定服务器证书的路径以及证书私钥的路径。
    • 来自本地文件系统的证书:浏览证书私钥的文件和服务器证书。
  6. 使用 TLS Termination 设置完 API 后,单击 Update Policy

另外:

  • 您可以通过单击加号 + 图标来添加更多证书。
  • 您还可以通过单击上下箭头来重新组织证书。

要保存您的更改,请点击 Update Policy Chain

4.1.23.2. 验证 TLS 终止策略的功能

先决条件

4.1.23.2.1. 验证策略功能

如果策略可使用以下命令,则可以在命令行中测试:

curl “${public_URL}:${port}/?user_key=${user_key}" --cacert ${path_to_certificate}/ca.pem -v

其中:

  • public_URL= staging 公共基本 URL
  • port= 端口号
  • user_key= 要进行身份验证的用户密钥
  • path_to_certificate= 本地文件系统中 CA 证书的路径

4.1.23.3. 从 TLS 终止中删除文件

本节论述了从 TLS 终止策略中删除证书和密钥文件的步骤。

先决条件

4.1.23.3.1. 删除证书
  1. 单击 TLS 终止 链接。
  2. 要删除证书和密钥,请单击 x 图标。
  3. 删除证书后,点击 Update Policy

要保存您的更改,请点击 Update Policy Chain

4.1.24. Upstream

通过 Upstream 策略,您可以使用正则表达式来解析主机请求标头,并将私有基本 URL 中定义的上游 URL 替换为不同的 URL。

例如:

具有 regex /foo 的策略和 URL 字段 newexample.com 将 URL https://www.example.com/foo/123/ 替换为 newexample.com

策略链参考:

属性描述必需?

regex

regex 属性允许您指定在搜索与请求路径匹配项时 Upstream 策略要使用的正则表达式。

数据类型:字符串,必须是一个有效的正则表达式语法

url

使用 url 属性,您可以在匹配项中指定替换 URL。请注意,Upstream 策略不会检查这个 URL 是否有效。

数据类型:字符串,确定这是有效的 URL

策略对象示例

{
  "name": "upstream",
  "version": "builtin",
  "configuration": {
    "rules": [
      {
        "regex": "^/v1/.*",
        "url": "https://api-v1.example.com",

      }
    ]
  }
}

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.25. 上游连接

根据您在 3scale 安装中配置 API 后端服务器的方式,为每个 API 更改以下指令的默认值:

  • proxy_connect_timeout
  • proxy_send_timeout
  • proxy_read_timeout

4.1.25.1. 在策略链中配置上游连接

本节介绍了在策略链中配置 Upstream 连接策略的步骤。

先决条件

  • 您需要有权访问 3scale 安装。
  • 您需要等待所有部署完成。
4.1.25.1.1. 配置策略
  1. 要将 Upstream 连接策略添加到 API,请按照 启用标准策略中 的步骤操作并选择 Upstream Connection
  2. 单击 Upstream Connection 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 配置与上游连接的选项:

    • send_timeout
    • connect_timeout
    • read_timeout
  5. 当您使用 Upstream Connection 设置 API 后,点 Update Policy

要保存您的更改,请点击 Update Policy Chain

4.1.26. Upstream Mutual TLS

使用 Upstream Mutual TLS 策略,您可以根据配置中设置的证书在 APIcast 和上游 API 之间建立 mutual TLS 连接。此策略支持多个上游 API 的证书。

4.1.26.1. 在策略链中配置上游 TLS

本节论述了在策略链中配置 Upstream Mutual TLS 策略的步骤。

先决条件

  • 您需要有权访问 3scale 安装。

流程

  1. 要将 Upstream Mutual TLS 策略添加到您的 API,请按照以下步骤 启用标准策略 并选择 Upstream Mutual TLS
  2. 单击 Upstream Mutual TLS 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 选择 证书类型

    • 路径 :如果要指定证书的路径,如 OpenShift 生成的证书。
    • 嵌入式 :如果要使用第三方生成的证书,请从您的文件系统中上传它。
  5. Certificate 中,指定客户端证书。
  6. Certificate key 中指定密钥。
  7. 使用 Upstream Mutual TLS 设置完 API 后,点 Update Policy Chain

推进您的更改:

  1. 进入 [Your_product] page > Integration > Configuration
  2. APIcast Configuration 下,点击 Promote v# to Staging APIcast

    • V# 代表要提升的配置的版本号。

4.1.27. URL Rewriting

URL 重写策略允许您修改请求的路径和查询字符串。

与 3scale APIcast 策略结合使用时,如果在策略链中的 APIcast 策略之前放置 URL 重写策略,APIcast 映射规则将应用到修改的路径。如果在 APIcast 链中的 APIcast 后放置了 URL 重写策略,则映射规则将应用到原始路径。

该策略支持以下两组操作:

  • 命令 :用于重写请求路径的命令列表。
  • query_args_commands :要应用的命令列表来重写请求的查询字符串。

4.1.27.1. 重写路径的命令

以下是 commands 列表中每个命令的配置参数,其中包括:

  • op:要应用的操作。可用的选项包括:subgsubsub 操作仅用您指定的正则表达式替换第一个匹配项。gsub 操作会将所有匹配项替换为您指定的正则表达式。请参阅有关 subgsub 操作的文档。
  • 正则表达式 :要匹配的与 Perl 兼容的正则表达式。
  • 替换 :替换在匹配项中使用的 : 替换字符串。
  • Options(可选):定义正则表达式的执行方式 的选项。有关可用选项的详情,请查看 OpenResty Lua 模块项目文档中的 ngx.re.match 部分。
  • break (可选):如果将设置为 true(已启用)时,如果命令重新编写了 URL,它将是最后应用的一个(将丢弃列表中的所有 posterior 命令)。

4.1.27.2. 重写查询字符串的命令

以下是 query_args_commands 列表中每个命令由以下部分组成的配置参数:

  • op: 操作要应用到查询参数。可用的选项如下:

    • 添加: 为现有参数添加一个值。
    • 设置 :在未设置时创建 arg,并在设置时替换其值。
    • push :在未设置时创建 arg,并在设置时添加值。
    • 删除 :删除 arg。
  • ARG :用于操作的查询参数名称。
  • :指定用于查询参数的值。对于值类型"liquid",值应当采用 {{ variable_from_context }} 格式。对于 delete 操作,不考虑该值。
  • value_type (可选):定义查询参数值的评估方式,可以是 纯文本 的纯文本,或者作为 Liquid 模板进行评估。更多信息请参阅 第 5.1 节 “在策略中使用变量和过滤器”。如果没有指定,则默认使用类型"plain"。

示例

URL 重写策略配置如下:

{
  "name": "url_rewriting",
  "version": "builtin",
  "configuration": {
    "query_args_commands": [
      {
        "op": "add",
        "arg": "addarg",
        "value_type": "plain",
        "value": "addvalue"
      },
      {
        "op": "delete",
        "arg": "user_key",
        "value_type": "plain",
        "value": "any"
      },
      {
        "op": "push",
        "arg": "pusharg",
        "value_type": "plain",
        "value": "pushvalue"
      },
      {
        "op": "set",
        "arg": "setarg",
        "value_type": "plain",
        "value": "setvalue"
      }
    ],
    "commands": [
      {
        "op": "sub",
        "regex": "^/api/v\\d+/",
        "replace": "/internal/",
        "options": "i"
      }
    ]
  }

发送到 APIcast 的原始请求 URI:

https://api.example.com/api/v1/products/123/details?user_key=abc123secret&pusharg=first&setarg=original

应用 URL 重写后 APIcast 发送到 API 后端的 URI:

https://api-backend.example.com/internal/products/123/details?pusharg=first&pusharg=pushvalue&setarg=setvalue

应用以下转换:

  1. 子字符串 /api/v1/ 匹配唯一的路径重写命令,它被 /internal/ 替换。
  2. 已删除 user_key 查询参数。
  3. pushvalue 作为 pusharg 查询参数的额外值添加。
  4. 查询参数 setargoriginal 值替换为配置的值 setvalue
  5. 命令 add 没有被应用,因为原始 URL 中不存在查询参数 addarg

有关如何配置策略的详情,请参考文档中 3scale 中的创建策略链 部分。

4.1.28. 使用 Captures 重写 URL

使用 Captures 策略的 URL Rewriting 是 第 4.1.27 节 “URL Rewriting” 策略的替代,并允许在将 API 请求传递给 API 后端前重写 API 请求的 URL。

URL 使用 Captures 策略检索 URL 中的参数,并在重写 URL 中使用其值。

该策略支持 transformations 配置参数。这是一个对象列表,用于描述将哪些转换应用到请求 URL。每个调整对象由两个属性组成:

  • match_rule :此规则与传入请求 URL 匹配。它可以包含 {nameOfArgument} 格式的命名参数;这些参数可以在重写 URL 中使用。将 URL 与 match_rule 进行比较,作为正则表达式。匹配指定参数的值必须只包含以下字符(在 PCRE regex 表示法中): [\w-.~%!$&'()*+,;=@:]+。可以在 match_rule 表达式中使用其他 regex 令牌,如 ^ 表示字符串开头,$ 代表字符串末尾。
  • 模板 :原始 URL 重写的 URL 模板;它可以使用 match_rule 中的命名参数。

原始 URL 的查询参数与 template 中指定的查询参数合并。

示例

使用 Captures 策略的 URL 重写配置如下:

{
  "name": "rewrite_url_captures",
  "version": "builtin",
  "configuration": {
    "transformations": [
      {
        "match_rule": "/api/v1/products/{productId}/details",
        "template": "/internal/products/details?id={productId}&extraparam=anyvalue"
      }
    ]
  }
}

发送到 APIcast 的原始请求 URI:

https://api.example.com/api/v1/products/123/details?user_key=abc123secret

应用 URL 重写后 APIcast 发送到 API 后端的 URI:

https://api-backend.example.com/internal/products/details?user_key=abc123secret&extraparam=anyvalue&id=123

4.2. 在 Admin Portal 中启用策略

执行以下步骤在 Admin Portal 中启用策略:

  1. 登录 3scale。
  2. 选择您要为其启用策略的产品 API。
  3. [your_product_name],进入到 Integration > Policies
  4. 在 POLIC IES 部分下,单击 Add policy
  5. 选择您要添加和填写所需字段的策略。
  6. 单击 Update Policy Chain 按钮,以保存策略链。

4.3. 创建自定义 APIcast 策略

您可以完全创建自定义 APIcast 策略,或修改标准策略。

要创建自定义策略,您必须了解以下内容:

  • 策略用 Lua 编写。
  • 策略必须遵循,并且必须放在正确的文件目录中。
  • 策略行为受到策略链中的放置方式的影响。
  • 完全支持添加自定义策略的接口,但不支持自定义策略本身。

4.4. 在 APIcast 中添加自定义策略

本文档概述了在 APIcast 中添加自定义策略以考虑不同的部署的详细信息。

4.4.1. 在 APIcast 部署中添加自定义策略

如果创建了自定义策略,则必须将它们添加到 APIcast 中。具体方法取决于 APIcast 部署的位置:

  • 您可以将自定义策略添加到以下 APIcast 自我管理的部署中: APIcast on OpenShift 和 Docker 容器化环境。
  • 您无法将自定义策略添加到 APIcast 托管。
警告

切勿直接在生产网关上进行策略更改。始终测试您的更改。

4.4.2. 在嵌入式 APIcast 中添加自定义策略

要将自定义 APIcast 策略添加到内部部署中,您必须构建包含自定义策略的 OpenShift 镜像,并将其添加到您的部署中。3scale 提供了一个示例存储库,您可以使用作为框架来创建和添加自定义策略到内部部署。

此示例存储库包含自定义策略的正确目录结构,以及用于创建镜像流和 BuildConfig 的模板,用于构建包含您创建的任何自定义策略的新 APIcast OpenShift 镜像。

警告

构建 apicast-custom-policies 时,构建过程会将新镜像推送到 amp-apicast:latest 标签。当此镜像流标签上的镜像更改时(:latest),apicast-stagingapicast-production 标签都默认配置为自动启动新部署。为了避免对生产服务(或暂存)造成任何中断(如果您愿意),请禁用自动部署(在镜像更改时"自动启动新部署 "),或者为生产环境配置不同的镜像流标签(例如 amp-apicast:production)。

在内部部署中添加自定义策略:

  1. 使用以下注意事项,使用您在创建 registry 服务帐户中创建的凭证创建 docker-registry secret:

    • your-registry-service-account-username 替换为以 12345678|username 创建的用户名。
    • your-registry-service-account-password 替换为用户名下面的密码字符串,位于 Token Information 选项卡下。
    • 为每个镜像流所在并使用 registry.redhat.io 的新命名空间 创建一个 docker-registry secret。

      运行这个命令来创建 docker-registry secret:

      oc create secret docker-registry threescale-registry-auth \
        --docker-server=registry.redhat.io \
        --docker-username="your-registry-service-account-username" \
        --docker-password="your-registry-service-account-password"
  2. 使用策略示例对 https://github.com/3scale/apicast-example-policy [public 软件仓库进行分叉,或使用其内容创建私有存储库。您需要在 Git 存储库中提供自定义策略的代码,供 OpenShift 构建该镜像。请注意,为了使用私有 Git 存储库,您必须在 OpenShift 中设置机密。
  3. 在本地克隆存储库,为您的策略添加实施,并将更改推送到您的 Git 存储库。
  4. 更新 openshift.yml 模板。特别是,更改以下参数:

    1. 策略 BuildConfig 中的 spec.source.git.uri: https://github.com/3scale/apicast-example-policy.git - 将它更改为 Git 存储库位置。
    2. 自定义策略 BuildConfig 中的 spec.source.images[0].paths.sourcePath: /opt/app-root/policies/example - 把 example 改为您在存储库中的 policies 目录下添加的自定义策略名称。
    3. (可选)更新 OpenShift 对象名称和镜像标签。但是,您必须确保更改是共同的(例如: apicast-example-policy BuildConfig 构建),并推送 apicast-policy:example 镜像,然后被 apicast-custom-policies BuildConfig 作为源使用。因此,标签应该相同。
  5. 运行以下命令来创建 OpenShift 对象:

    oc new-app -f openshift.yml --param AMP_RELEASE=2.8
  6. 如果构建没有自动启动,请运行以下两个命令:如果您更改了它,请将 apicast-example-policy 替换为您自己的 BuildConfig 名称(如 apicast-<name>-policy)。等待第一个命令完成,然后执行第二个命令。

    oc start-build apicast-example-policy
    oc start-build apicast-custom-policies

如果内置 APIcast 镜像跟踪 amp-apicast:latest 镜像流中的更改,则 APIcast 的新部署将启动。apicast-staging 重启后,导航到 Integration > Policies,然后点击 Add Policy 按钮来查看列出的自定义策略。选择并配置后,单击 Update Policy Chain,使自定义策略在暂存 APIcast 中正常工作。

4.4.3. 在另一个 OpenShift Container Platform 上将自定义策略添加到 APIcast 中

您可以通过从集成的 OpenShift Container Platform 注册表获取包含自定义策略的镜像,将自定义策略添加到 OpenShift Container Platform (OCP)上的 APIcast。

在另一个 OpenShift Container Platform 上将自定义策略添加到 APIcast 中

  1. 在 APIcast 内置中添加策略
  2. 如果您没有在 OpenShift 主集群中部署 APIcast 网关,请 建立对主 OpenShift 集群上的内部注册表的访问
  3. 下载 3scale 2.8 APIcast OpenShift 模板。
  4. 要修改模板,请将默认 镜像 目录替换为内部注册表中的完整镜像名称。

    image: <registry>/<project>/amp-apicast:latest
  5. 使用 OpenShift 模板部署 APIcast,指定自定义镜像:

    oc new-app -f customizedApicast.yml
注意

当自定义策略添加到 APIcast 并构建新镜像时,当 APIcast 使用镜像部署时,这些策略将自动显示在管理门户中。现有服务可以在可用策略列表中看到此新策略,因此可以在任何策略链中使用。

从镜像中删除自定义策略并重启 APIcast 时,该策略将不再在列表中可用,因此您无法再将它添加到策略链中。

4.5. 在 3scale 中创建策略链

作为 APIcast 网关配置的一部分,在 3scale 中创建策略链。按照以下步骤修改管理门户中的策略链:

  1. 登录 3scale。
  2. 导航到您要为其配置策略链的 API 产品。
  3. [your_product_name] > Integration > Policies 中,点 Add policy
  4. Policy Chain 部分下,使用箭头图标来重新排序策略链中的策略。始终将 3scale APIcast 策略放在策略链中。

    policyChainOverview
  5. 单击 Update Policy Chain 按钮,以保存策略链。

4.6. 创建策略链 JSON 配置文件

如果您使用原生部署 APIcast,您可以创建一个 JSON 配置文件来控制 AMP 之外的策略链。

JSON 配置文件策略链包含一个由以下信息组成的 JSON 数组:

  • 带有 id 值的 services 对象,用于指定策略链按照数字应用到哪个服务
  • proxy 对象,其中包含 policy_chain 和后续对象
  • policy_chain 对象,其中包含定义策略链的值
  • 单个 策略对象,用于指定识别策略和配置策略行为所需的名称和 配置数据

以下是自定义策略 sample_policy_1 和 API 内省标准策略 token_introspection 的策略链示例:

{
  "services":[
    {
      "id":1,
      "proxy":{
        "policy_chain":[
          {
            "name":"sample_policy_1", "version": "1.0",
            "configuration":{
              "sample_config_param_1":["value_1"],
              "sample_config_param_2":["value_2"]
            }
          },
          {
            "name": "token_introspection", "version": "builtin",
            "configuration": {
              introspection_url:["https://tokenauthorityexample.com"],
              client_id:["exampleName"],
              client_secret:["secretexamplekey123"]
          },
          {
             "name": "apicast", "version": "builtin",
          }
        ]
      }
    }
  ]
}

所有策略链都必须包含内置策略 APIcast。将 APIcast 置于策略链中的位置将影响策略行为。

第 5 章 将策略链与 APIcast 原生部署集成

对于原生 APIcast 部署,您可以通过使用 THREESCALE_CONFIG_FILE 环境变量指定配置文件来集成 自定义策略链。以下示例指定了配置文件 example.json

THREESCALE_CONFIG_FILE=example.json bin/apicast

5.1. 在策略中使用变量和过滤器

一些 第 4.1 节 “APIcast 标准策略” 支持 Liquid 模板,它允许使用纯文本值,还包括在请求上下文中存在的变量。

要使用上下文变量,将其名称打包在 {{}} 中,例如: {{ uri }}。如果变量是对象,您也可以访问其属性,例如: {{ somevar.attr }}

以下是所有策略中的标准变量:

  • URI :带有查询参数的请求路径不包括在此路径中。嵌入式 NGINX 变量的值 $uri
  • 主机 :请求的主机(内嵌的 NGINX 变量 $host的值)。
  • REMOTE_ADDR:客户端的 IP 地址(嵌入式 NGINX 变量的值 $ remote_addr )。
  • 标头 :包含请求标头的对象。使用 {{headers['Some-Header']}} 获取特定的标头值。
  • http_method :请求方法:GET、POST 等。

这些标准变量在请求的上下文中使用,但策略可以在上下文中添加更多变量。阶段是指 APIcast 具有的所有执行步骤。在以下情况下,策略链中的所有策略都可以使用变量:

  • 在同一阶段中,如果在策略中添加了变量,然后在添加后在以下策略中使用。
  • 如果在阶段中添加变量,则可在后续阶段使用此变量。

以下是标准 3scale APIcast 策略添加到上下文中的变量示例:

  • JWT :用于 OpenID Connect 身份验证的 JWT 令牌的解析 JSON 载荷。
  • Credentials :包含应用凭证的对象。示例:" app_id": "972f7b4f", "user_key": "13b668c4d1e10eaebaa5144b4749713f".
  • Service :包含当前请求的服务配置的对象。示例:服务 ID 将为 {{ service.id }}。

有关上下文中可用对象和值的完整列表,请查看 第 4.1.12 节 “Liquid Context Debug”

变量配合 Liquid 模板使用。示例: {{ remote_addr }}{{ headers['Some-Header'] }}{{ jwt.aud }}.支持值变量的策略具有一个特殊参数,通常带有 _type 后缀(例如: value_typename_type 等等),它接受两个值:"plain"表示纯文本,"liquid"用于 liquid 模板。

APIcast 还支持 Liquid 过滤器,可应用于变量的值。过滤器将 NGINX 功能应用到 Liquid 变量的值。

过滤器在变量输出标签 {{ }} 中放置,紧随变量的名称或通过竖线字符 | 和过滤器的名称来排列的字面值。示例:

  • {{ 'username:password' | encode_base64 }},其中 username:password 是变量。
  • {{ uri | escape_uri }}

有些过滤器不需要参数,因此您可以使用空字符串而不是 变量。示例: {{ '' | utctime }} 将以 UTC 时区返回当前时间。

过滤器可以按如下所示链接:{{ variable | function1 | function2 }}。示例: {{ '' | utctime |scap_uri }}.

以下是可用功能列表:

第 6 章 使用 Fuse 中的策略扩展转换 3scale 消息内容

您可以使用 Red Hat Fuse 为 Red Hat 3scale API Management 创建高度灵活的策略扩展。您可以通过在 OpenShift 上的 Fuse 中创建策略扩展,并在 3scale 管理门户中配置它们。这可让您使用 APIcast 代理策略来执行复杂的转换来请求/响应消息内容(例如,XML 到 JSON),并在 Apache Camel 集成框架中实施。

这也允许您在 Camel 中动态添加或修改自定义策略扩展,而不是重建并重新部署静态 APIcast 容器镜像。您可以使用任何使用 Camel 域特定语言(DSL)提供的 Camel 企业集成模式(EIP)来实现 APIcast 策略扩展。这可让您使用熟悉的编程语言(如 Java 或 XML)编写策略扩展。本主题的示例使用 Camel Netty4 HTTP 组件在 Java 中实施 HTTP 代理。

所需的软件组件

您必须在同一 OpenShift 集群中部署以下 Red Hat 集成组件:

  • OpenShift 7.6 上的 Fuse
  • 3scale On-premises
  • APIcast 自我管理或嵌入
注意

您应该在同一 OpenShift 集群上安装这些组件,但不一定要在同一命名空间或项目中。Fuse 和 3scale 之间没有直接通信。所有通信均仅通过 OpenShift 进行。

从架构角度而言,最好将 Fuse 自定义代码在不同于 3scale 项目中运行。但是,您必须确保两个项目间的通信成为可能。详情请参阅使用 OpenShift SDN 配置网络策略

6.1. 在 Fuse 中集成 APIcast 与 Apache Camel 转换

您可以将 APIcast 与在 OpenShift 上的 Fuse 中编写为 Apache Camel 应用程序转换进行集成。当在 3scale 中配置和部署策略扩展后,3scale 流量将经由 Camel 策略扩展,该扩展将转换消息内容。在这种情况下,Camel 充当反向 HTTP 代理,APIcast 将 3scale 流量发送到 Camel,然后 Camel 会将流量发送到 API 后端。

本主题的示例使用 Camel Netty4 HTTP 组件创建 HTTP 代理:

  • 通过 HTTP 代理协议接收的请求将转发到目标服务,并将 HTTP 正文转换为大写。
  • 目标服务的响应是通过将其转换为大写,然后返回到客户端来处理的。

先决条件

  • 您必须在 OpenShift 7.6 和 3scale 2.8 上部署了 Fuse,并且部署在同一 OpenShift 集群上。有关安装详情,请参阅:

  • 您将需要集群管理员特权,以便在 OpenShift 和 3scale 上安装 Fuse 并创建项目。但是,您可以创建部署配置、部署容器集,或者创建具有每个项目编辑访问权限的服务。

流程

  1. 在 Java 中编写 Apache Camel 应用程序,使用 Camel netty4-http 组件来实施 HTTP 代理。然后,您可以使用任何 Camel 组件转换消息。

    以下简单示例执行请求的大写和来自服务的响应:

    import java.util.Locale;
    import org.apache.camel.Exchange;
    import org.apache.camel.Message;
    import org.apache.camel.builder.RouteBuilder;
    
    public class ProxyRoute extends RouteBuilder {
    
        @Override
        public void configure() throws Exception {
            from("netty4-http:proxy://0.0.0.0:8080")
                .process(ProxyRoute::uppercase)
                .toD("netty4-http:"
                    + "${headers." + Exchange.HTTP_SCHEME + "}://"
                    + "${headers." + Exchange.HTTP_HOST + "}:"
                    + "${headers." + Exchange.HTTP_PORT + "}"
                    + "${headers." + Exchange.HTTP_PATH + "}")
                .process(ProxyRoute::uppercase);
        }
    
        public static void uppercase(final Exchange exchange) {
            final Message message = exchange.getIn();
            final String body = message.getBody(String.class);
            message.setBody(body.toUpperCase(Locale.US));
        }
    }
  2. 按照 在 OpenShift 中创建和部署 Fuse 所述,部署您的 Camel 应用程序
注意

本例中不支持 HTTP over TLS(HTTPS)协议。

6.2. 配置使用 OpenShift 上 Fuse 中的 Apache Camel 创建的 APIcast 策略扩展

创建 Apache Camel 转换后,您可以在 3scale 管理门户中的策略链中将其配置为策略扩展。

策略扩展可让您配置 3scale 产品以使用 HTTP 代理。此服务用于通过 HTTP 代理发送 3scale 流量,以便在第三方代理中执行请求/响应性修改。在这种情况下,第三方代理是在 OpenShift 的 Fuse 中实施的。

注意

策略扩展代码在 OpenShift 上的 Fuse 中的 Apache Camel 应用程序中创建,且无法从 3scale 中修改或删除。

先决条件

  • 您必须在 OpenShift 7.6 和 3scale 2.8 上部署了 Fuse,并且部署在同一 OpenShift 集群上。有关安装详情,请参阅:

  • 您必须在 OpenShift 的 Fuse 中使用 Apache Camel 应用程序实施 3scale 策略扩展。
  • 您必须已在 Pod 中部署了 Apache Camel 应用程序,并将其作为服务在 OpenShift 中公开。如需了解更多详细信息,请参阅在 OpenShift 的 Fuse 上创建和部署应用程序

流程

  1. 选择 Integration > Configuration > edit APIcast configuration in the 3scale Admin Portal。
  2. 选择 POLICIES > Add Policy > Proxy service
  3. 在适当的字段中输入 Camel 代理服务的路由:

    • HTTPS_ PROXY:连接到 HTTPS 代理服务。
    • HTTP_ PROXY :连接到 HTTP 代理服务。
    • all_proxy: 在未指定协议时连接到服务。

      例如,以下显示了 HTTP 代理服务的路由:

      http://camel-proxy.my-3scale-management-project.svc
  4. 点击 staging 环境中的 Update & test 以应用新的代理策略。
  5. 使用 curl 测试 HTTP 代理:例如:

    curl "https://testapi-3scale-apicast-staging.myuser.app.dev.3sca.net:443/?user_key=MY_USER_KEY" -k
  6. 确认消息内容已转换,本例中将转换为大写。

第 7 章 APIcast 环境变量

APIcast 环境变量允许您修改 APIcast 的行为。以下值是受支持的环境变量:

注意
  • 不支持或已弃用的环境变量不会被列出
  • 有些环境变量功能可能已移到 APIcast 策略

all_proxy,ALL_PROXY

Default: no value Value: string Example: http://forward-proxy:80

定义要在未指定特定于协议的代理时用于连接服务的 HTTP 代理。不支持身份验证。

APICAST_ACCESS_LOG_FILE

Default: stdout

定义将存储访问日志的文件。

APICAST_BACKEND_CACHE_HANDLER

Values: strict | resilient

Default: strict

弃用 : 使用 缓存 策略。

定义当后端不可用时授权缓存的行为方式。当后端不可用时,请严格删除缓存的应用。弹性仅在从后端获取授权时才会这样做。

APICAST_CONFIGURATION_CACHE

:数字

默认 : 0

指定配置要存储的时间间隔(以秒为单位)。该值应设置为 0(不兼容 APICAST_CONFIGURATION_LOADER的引导值)或超过 60 个。例如,如果 APICAST_CONFIGURATION_CACHE 设为 120,则网关将每 2 分钟从 API 管理器重新加载配置(120 秒)。值 < 0 禁用重新加载。

APICAST_CONFIGURATION_LOADER

:boot | lazy

默认 : lazy

定义如何加载配置。启动将在网关启动时向 API 管理器请求配置。lazy 将根据每个传入请求按需加载(保证对每个请求 APICAST_CONFIGURATION_CACHE 应该为 0 完全刷新)。

APICAST_CUSTOM_CONFIG

已弃用 : 使用 策略 替代。

定义实施自定义逻辑的 Lua 模块的名称,覆盖现有的 APIcast 逻辑。

APICAST_ENVIRONMENT

Default:

Value: string[:]

示例 :production:cloud-hosted

APIcast 应加载以冒号(:)分隔的环境(或路径)列表。此列表可以替代 CLI 上的 -e--environment 参数,例如,存储在容器镜像中作为默认环境。CLI 上传递的任何值都会覆盖此变量。

APICAST_EXTENDED_METRICS

默认 :false

:布尔值

示例 :"true"

启用 Prometheus 指标的附加信息。以下指标有 service_idservice_system_name 标签,它们提供了有关 APIcast 的更多深入详情:

  • total_response_time_seconds
  • upstream_response_time_seconds
  • upstream_status

APICAST_HTTPS_CERTIFICATE

Default: 没有值

HTTPS 的 PEM 格式带有 X.509 证书的文件路径。

APICAST_HTTPS_CERTIFICATE_KEY

Default: 没有值

使用 PEM 格式的 X.509 证书 secret 密钥的文件路径。

APICAST_HTTPS_PORT

Default: 没有值

控制哪些端口 APIcast 应开始侦听 HTTPS 连接。如果此冲突与 HTTP 端口冲突,它将仅用于 HTTPS。

APICAST_HTTPS_VERIFY_DEPTH

默认 : 1

:正整数。

定义客户端证书链的最大长度。如果此参数的值有 1,则可以在客户端证书链中包含额外证书。例如,root 证书认证机构。

APICAST_LOAD_SERVICES_WHEN_NEEDED

Values:

  • true1 用于 true
  • false0 或空用于 false

默认false

当配置了多个服务时,可以使用此选项。但是,其性能取决于其他因素,例如服务数量、APIcast 和 3scale 管理门户之间的延迟,以及配置的生存时间(TTL)。

默认情况下,APIcast 每次从管理门户下载其配置时加载所有服务。启用这个选项后,配置将使用延迟加载。APIcast 将仅加载为请求的主机标头中指定的主机配置的主机。

注意

APICAST_LOG_FILE

默认 : stderr

定义包含 OpenResty 错误日志的 文件。文件供 error_log 指令中的 bin/apicast 使用。文件路径可以是绝对的,也可以是相对于 APIcast 前缀目录。请注意,默认前缀目录为 APIcast。如需更多信息,请参阅 NGINX 文档

APICAST_LOG_LEVEL

:debug | info | notice | warn | error | crit | alert | emerg

默认 :warn

指定 OpenResty 日志的日志级别。

APICAST_MANAGEMENT_API

Values:

  • disabled :完全禁用,只侦听端口
  • status :仅为健康检查启用 /status/ 端点
  • debug :会打开完整的 API

管理 API 功能强大,可以控制 APIcast 配置。您应该只为调试启用 debug 级别。

APICAST_MODULE

默认 :apicast

已弃用 : 使用 策略 替代。

指定实施 API 网关逻辑的主 Lua 模块的名称。自定义模块可以覆盖默认 apicast.lua 模块的功能。请参阅有关如何使用模块的示例

APICAST_OIDC_LOG_LEVEL

:debug | info | notice | warn | error | crit | alert | emerg

默认 :err

允许为与 OpenID Connect 集成相关的日志设置日志级别。

APICAST_PATH_ROUTING

  • true1 用于 true
  • false0 或空用于 false

当此参数设置为 true 时,除了基于主机的默认路由外,网关还将使用基于路径的路由。API 请求将从请求的 Host 标头值与公共基础 URL 匹配的服务列表中路由到具有匹配映射规则的第一个服务。

APICAST_PATH_ROUTING_ONLY

  • true1 用于 true
  • false0 或空用于 false

当此参数设置为 true 时,网关将使用基于路径的路由,并且不会回退到基于主机的默认路由。API 请求将从请求的 Host 标头值与公共基础 URL 匹配的服务列表中路由到具有匹配映射规则的第一个服务。

此参数的优先级高于 APICAST_PATH_ROUTING。如果启用了 APICAST_PATH_ROUTING_ONLY,APIcast 将只执行基于路径的路由,无论 APICAST_PATH_ROUTING 的值为何。

APICAST_POLICY_LOAD_PATH

默认APICAST_DIR/policies

Value: string[:]

示例~/apicast/policies:$PWD/policies

冒号(:)分隔的路径列表,APIcast 应该在其中查找策略。它可用于首先从开发目录加载策略或加载示例。

APICAST_PROXY_HTTPS_CERTIFICATE

Default:

:字符串

示例 :/home/apicast/my_certificate.crt

APIcast 与上游连接时将使用的客户端 SSL 证书的路径。请注意,此证书将用于配置中的所有服务。

APICAST_PROXY_HTTPS_CERTIFICATE_KEY

Default:

:字符串

示例 :/home/apicast/my_certificate.key

客户端 SSL 证书密钥的路径。

APICAST_PROXY_HTTPS_PASSWORD_FILE

Default:

:字符串

示例 :/home/apicast/passwords.txt

使用 APICAST_PROXY_HTTPS_CERTIFICATE_KEY 指定 SSL 证书密钥的密语文件的路径。

APICAST_PROXY_HTTPS_SESSION_REUSE

默认 : on

  • on :重用 SSL 会话。
  • off :不重复使用 SSL 会话。

APICAST_REPORTING_THREADS

默认 : 0

:整数 >= 0

实验性: 在极端负载可能具有无法预计的性能并丢失报告。

大于 0 的值将启用对后端的带外报告。这是一个全新的 实验 功能,用于提高性能。客户端不会看到后端延迟,一切都将异步处理。这个值决定了在客户端因增加延迟而节流前可以同时运行多少异步报告。

APICAST_RESPONSE_CODES

  • true1 用于 true
  • false0 或空用于 false

默认 :<empty>(false)

当设置为 true 时,APIcast 将记录 3scale 中 API 后端返回的响应代码。在 3scale 客户门户网站上查找响应代码功能的更多信息

APICAST_SERVICE_${ID}_CONFIGURATION_VERSION

${ID} 替换为实际的服务 ID。该值应当是您可以在管理门户的配置历史记录中看到的配置版本。将它设置为特定版本将阻止它自动更新,并且始终使用该版本。

APICAST_SERVICES_LIST

value :以逗号分隔的服务 ID 列表

APICAST_SERVICES_LIST 环境变量用于过滤您在 3scale API Manager 中配置的服务。这仅应用网关中特定服务的配置,从而丢弃未在列表中指定的服务标识符。您可以在 Products > [Your_product_name] > Overview 下的 Admin Portal 中找到您的产品的服务标识符,然后参阅 Configuration、Methods 和 Settings 以及 API 调用的 ID

APICAST_SERVICES_FILTER_BY_URL

:PCRE(Perl 兼容正则表达式),如 *.example.com

过滤 3scale API Manager 中配置的服务。

此过滤器与公共基本 URL 匹配。与过滤器不匹配的服务将被丢弃。如果无法编译正则表达式,则不会加载任何服务。

注意

如果服务不匹配但包含APICAST_SERVICES_LIST”一节 中,则不会丢弃该服务。

例 7.1. example

Regexp 过滤器 http://.*.foo.dev 应用到以下后端端点:

在这种情况下,13 在嵌入的 APIcast 和 2 中被丢弃。

APICAST_UPSTREAM_RETRY_CASES

: error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off

注意

这只在配置了重试策略并且指定何时应重试对上游 API 的请求时使用。它接受与 Nginx 的 PROXY_NEXT_UPSTREAM 模块 相同的值。

APICAST_WORKERS

默认 :auto

: number | auto

这是 nginx worker_processes 指令 中使用的值。默认情况下,APIcast 使用 auto,但使用 1 的开发环境除外。

BACKEND_ENDPOINT_OVERRIDE

从配置覆盖后端端点的 URI。在 OpenShift 外部部署 AMP 时非常有用.示例https://backend.example.com.

HTTP_KEEPALIVE_TIMEOUT

默认 :75 :正整数 示例1

此参数设置一个超时,期间 keep-alive 客户端连接将在服务器端保持打开状态。零值禁用 keep-alive 客户端连接。

默认情况下,网关会禁用 HTTP_KEEPALIVE_TIMEOUT。此配置允许使用默认值为 75 秒 的 NGINX 中保留超时。

HTTP_PROXY,HTTP_PROXY

Default: no value Value: string Example: http://forward-proxy:80

定义用于连接 HTTP 服务的 HTTP 代理。不支持身份验证。

HTTPS_PROXY,HTTPS_PROXY

Default: no value: string Example:https://forward-proxy:443

定义用于连接 HTTPS 服务的 HTTP 代理。不支持身份验证。

NO_PROXY,NO_PROXY

default: no value : string\[,<string>\]; *Example:foo,bar.com,.extra.dot.com

定义不应代理请求的主机名和域名的逗号分隔列表。设置为单个 * 字符(匹配所有主机)有效禁用代理。

OPENSSL_VERIFY

  • 0,false: 禁用对等验证
  • 1, true :启用对等验证

控制 OpenSSL 对等验证.它默认为 off,因为 OpenSSL 无法使用系统证书存储。它需要自定义证书捆绑包并将其添加到可信证书中。

建议您使用 https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate 并指向由 export-builtin-trusted-certs 生成的证书捆绑包。

OPENTRACING_CONFIG

此环境变量用于决定 opentracing tracer 的配置文件,如果未设置 OPENTRACING_TRACER,则忽略此变量。

每个 tracer 都有一个默认配置文件:* jaeger: conf.d/opentracing/jaeger.example.json

通过使用此变量设置文件路径,您可以选择挂载与默认情况下提供的不同的配置。

示例/tmp/jaeger/jaeger.json

OPENTRACING_HEADER_FORWARD

默认uber-trace-id

此环境变量控制用于转发 Opentracing 信息的 HTTP 标头,此 HTTP 标头将转发到上游服务器。

OPENTRACING_TRACER

示例jaeger

此环境变量控制将加载的追踪库,现在只有一个打开追踪器可用,即 jaeger

如果为空,将禁用 opentracing 支持。

RESOLVER

允许指定将由 OpenResty 使用的自定义 DNS 解析器。如果 RESOLVER 参数为空,则会自动发现 DNS 解析器。

THREESCALE_CONFIG_FILE

带有网关配置的 JSON 文件的路径。您必须提供 THREESCALE_PORTAL_ENDPOINTTHREESCALE_CONFIG_FILE 才能成功运行网关。在这两个环境变量中,THREESCALE_CONFIG_FILE 采用优先权。

Proxy Config ShowProxy Config Show Latest 端点也按 service 和 Proxy Configs List 服务限定。您必须知道服务的 ID。使用以下选项:

  • 使用 Proxy Configs List 供应商端点: < schema>://<admin-portal-domain>/admin/api/account/proxy_configs/<env>.json

    • 端点返回该提供程序的所有已存储代理配置,而不仅仅是每个服务的最新代理配置。迭代 JSON 返回的 proxy_configs 数组,并选择 proxy_config.content,其 proxy_config.version 都是具有相同 proxy_config.content.id 的所有代理配置之间的最高,即服务 ID。
  • 使用 Service List 端点: /admin/api/services.json

    • 端点列出了提供程序的所有服务。迭代服务的数组,每个服务都使用 Proxy Config Show Latest 端点,该端点由服务限定。

当使用容器镜像部署网关时:

  1. 将 文件配置为只读卷。
  2. 指定指示挂载卷的位置的路径。

您可以在 Example 文件夹中找到 示例 配置文件。

THREESCALE_DEPLOYMENT_ENV

: stage | production

默认 :production

此环境变量的值定义从中下载配置的环境;在使用新 APIcast 时是 3scale staging 或 production。

这个值也会在对 3scale Service Management API 的 authorize/report 请求的 header X-3scale-User-Agent 中使用。3scale 仅将它用于统计数据目的。

THREESCALE_PORTAL_ENDPOINT

以以下格式包含密码和门户端点的 URI:

<schema>://<password>@<admin-portal-domain>.

其中:

  • <password> 可以是 3scale 帐户管理 API 的供应商密钥访问令牌
  • <admin-portal-domain> 是要登录到 3scale 管理门户的 URL 地址。

示例https://access-token@account-admin.3scale.net

当提供了 THREESCALE_PORTAL_ENDPOINT 环境变量时,网关会在初始化时从 3scale 下载配置。配置包括 API 的 Integration 页面中提供的所有设置。

您还可以使用此环境变量 创建具有主管理门户的单一网关

需要为 网关提供成功运行的 THREESCALE_PORTAL_ENDPOINTTHREESCALE_CONFIG_FILE (优先)。

第 8 章 配置 APIcast 以获得更好的性能

本文档提供了在 APIcast 中调试性能问题的一般准则。它还介绍了可用的缓存模式,并解释了它们如何帮助提高性能,以及分析模式的详细信息。内容由以下部分构成:

8.1. 常规指南

在典型的 APIcast 部署中,需要考虑三个组件:

  • APIcast
  • 3scale 后端服务器,用于授权请求并跟踪其使用情况
  • 上游 API

在 APIcast 中遇到性能问题时:

  • 识别负责这些问题的组件。
  • 测量上游 API 的延迟,以确定 APIcast 加上 3scale 后端服务器的延迟。
  • 利用您用于运行基准测试的相同工具,执行新的测量,但指向 APIcast,而不是直接指向上游 API。

比较这些结果可让您了解 APIcast 和 3scale 后端服务器带来的延迟。

在带有自我管理的 APIcast 的托管(SaaS)安装中,如果 APIcast 和 3scale 后端服务器引入的延迟较高:

  1. 从部署了 APIcast 的同一机器向 3scale 后端服务器发出请求
  2. 测量延迟.

3scale 后端服务器公开返回版本: https://su1.3scale.net/status 的端点。相比之下,授权调用需要更多资源,因为它验证键、限值和队列后台作业。虽然 3scale 后端服务器在几毫秒内执行这些任务,但它的工作要比检查 /status 端点所执行的版本更多。例如,如果对 /status 的请求从 APIcast 环境中大约需要 300 毫秒,则每个未缓存的请求将花费更多时间。

8.2. 默认缓存

对于没有缓存的请求,这些是事件:

  1. APIcast 从匹配的映射规则中提取用量指标。
  2. APIcast 将指标加上应用凭据发送到 3scale 后端服务器。
  3. 3scale 后端服务器执行以下操作:

    1. 检查应用密钥,并且报告的指标使用量是否在定义的限制之内。
    2. 对后台作业排队,以增加所报告指标的使用量。
    3. 响应 APIcast 请求是否应授权。
  4. 如果请求被授权,请求将转至上游.

在这种情况下,请求不会到达上游,直到 3scale 后端服务器响应为止。

另一方面,使用默认启用的缓存机制:

  • APIcast 将存储在缓存中,如果已授权,则向 3scale 后端服务器授权调用的结果。
  • 下一个具有相同凭据和指标的请求将使用该缓存的授权,而不是前往 3scale 后端服务器。
  • 如果请求未获得授权,或者 APIcast 首次收到凭据,APIcast 将同步调用 3scale 后端服务器,如上方所述。

缓存身份验证后,APIcast 首先调用上游,然后在名为 post 操作的 阶段中,它将调用 3scale 后端服务器并在缓存中存储授权,使它准备好下一请求。请注意,对 3scale 后端服务器的调用不会引入任何延迟,因为它不会在请求时间发生。但是,在同一连接中发送的请求将需要等待后续 操作 阶段结束。

想象一下,客户端使用 keep-alive 并每秒发送请求的情况。如果上游响应时间为 100 ms,3scale 后端服务器的延迟为 500 毫秒,客户端每次都会获得 100 毫秒的响应。上游响应和报告总共需要 600 毫秒。这在下一请求到来前额外提供了 400 毫秒。

下图说明了默认的缓存行为。缓存机制的行为可以使用 缓存策略 来更改。

默认缓存行为

8.3. 异步报告线程

APIcast 具备启用对 3scale 后端服务器授权的线程池的功能。启用此功能后,APIcast 首先调用 3scale 后端服务器,以验证应用和指标是否与映射规则匹配。这与使用默认启用的缓存机制时类似。不同之处在于,只要池中存在可用报告线程,对 3scale 后端服务器的后续调用就完全异步报告。

报告线程对整个网关而言是全局的,在所有服务之间共享。进行第二个 TCP 连接时,只要已缓存授权,它也会完全异步。如果没有免费的报告线程,同步模式将返回标准异步模式,并在后的操作阶段报告。

您可以使用 APICAST_REPORTING_THREADS 环境变量启用此功能。

下图说明了异步报告线程池的工作方式。

异步报告线程池行为

8.4. 3scale 批处理器策略

默认情况下,APIcast 会为接收的每个请求对 3scale 后端服务器执行一个调用。3scale Batcher 策略的目标是通过显著减少向 3scale 后端服务器发出的请求数量来缩短延迟并提高吞吐量。为实现这一目标,此策略会缓存授权状态和批处理报告。

第 4.1.2 节 “3scale Batcher” 提供有关 3scale 批处理程序策略的详细信息。下图说明了策略的工作原理。

3scale 批处理器策略行为

第 9 章 向 Prometheus 公开 3scale APIcast Metrics

重要

在这个 3scale 发行版本中,不支持 Prometheus 安装和配置。另外,您可以使用 Prometheus 的社区版本 视觉化 API 服务的指标和警报。

9.1. 关于 Prometheus

Prometheus 是一个开源系统监控工具包,可用于监控在红帽 OpenShift 环境中部署的 3scale APIcast 服务。

如果要使用 Prometheus 监控服务,您的服务必须公开 Prometheus 端点。此端点是一个 HTTP 接口,公开指标列表和指标的当前值。Prometheus 定期提取这些目标定义的端点,并将收集的数据写入其数据库中。

9.1.1. Prometheus 查询

在 Prometheus UI 中,您可以使用 Prometheus Query Language(PromQL)编写查询来提取指标信息。使用 PromQL,您可以实时选择和聚合时间序列数据。

例如,您可以使用以下查询为指标名称 http_requests_total 选择 Prometheus 在最后 5 分钟内记录的所有值:

http_requests_total[5m]

您可以通过为指标指定 label (键:值对)来进一步定义或过滤查询的结果。例如,您可以查询以下查询,为指标名称 http_requests_totaljob 标签设置为 integration 的所有时间序列选择 Prometheus 在最后 5 分钟内记录的所有值:

http_requests_total{job="integration"}[5m]

查询的结果可以显示为一个图形,在 Prometheus 的表达式浏览器中作为表格数据查看,或者通过使用 Prometheus HTTP API 由外部系统使用。Prometheus 提供数据的图形视图。要获得更强大的图形仪表板来查看 Prometheus 指标,Grafana 是一种常见选择。

您还可以使用 PromQL 语言在 Prometheus alertmanager 工具中配置警报。

注意

Grafana 是社区支持的功能。红帽生产服务级别协议(SLA)不支持部署 Grafana 来监控 Red Hat 3scale 产品。

9.2. APIcast 与 Prometheus 集成

以下部署选项提供了与 Prometheus 的 APIcast 集成:

  • 自我管理的 APIcast(包括托管或内部 API 管理器)
  • 内置 APIcast 内部
注意

托管 API Manager 和托管的 APIcast 不提供与 Prometheus 的 APIcast 集成。

默认情况下,Prometheus 可以监控 表 9.2 “用于 3scale APIcast 的 Prometheus 默认指标” 中列出的 APIcast 指标。

9.2.1. 其他选项

另外,如果您有集群管理员对 OpenShift 集群的访问权限,您可以扩展 total_response_time_seconds, upstream_response_time_seconds, and upstream_status metrics to include service_idservice_system_name 标签。要扩展这些指标,使用以下命令将 APICAST_EXTENDED_METRICS OpenShift 环境变量设置为 true

oc set env dc/apicast APICAST_EXTENDED_METRICS=true

如果您使用 APIcast Batch 策略(描述在 第 4.1.2 节 “3scale Batcher”中),Prometheus 也可以监控 表 9.3 “3scale APIcast 批处理策略的 Prometheus Metrics” 中列出的指标。

注意

如果指标没有值,Prometheus 会隐藏指标数据。例如,如果 nginx_error_log 没有报告错误,Prometheus 不会显示 nginx_error_log 指标。nginx_error_log 指标只有在有值时才可见。

其他资源

有关 Prometheus 的详情,请参考 Prometheus:入门

9.3. 3scale APIcast 的 OpenShift 环境变量

要配置 Prometheus 实例,您可以设置 表 9.1 “3scale APIcast 的 Prometheus 环境变量” 中描述的 OpenShift 环境变量。

表 9.1. 3scale APIcast 的 Prometheus 环境变量

环境变量描述默认

APICAST_EXTENDED_METRICS

一个布尔值,启用 Prometheus 指标的额外信息。以下指标有 service_idservice_system_name 标签,它们提供了有关 APIcast 的更多深入详情:

  • total_response_time_seconds
  • upstream_response_time_seconds
  • upstream_status

false

其他资源

有关设置环境变量的详情,请查看相关的 OpenShift 指南:

有关支持的配置的详情,请参考 Red Hat 3scale API 管理支持的配置 页面。

9.4. 3scale APIcast 指标公开给 Prometheus

在将 Prometheus 设置为监控 3scale APIcast 后,它默认可以监控 表 9.2 “用于 3scale APIcast 的 Prometheus 默认指标” 中列出的指标。

只有在使用 第 4.1.2 节 “3scale Batcher” 时,表 9.3 “3scale APIcast 批处理策略的 Prometheus Metrics” 中列出的指标才可用。

表 9.2. 用于 3scale APIcast 的 Prometheus 默认指标

指标描述类型标签

nginx_http_connections

HTTP 连接数

gauge

state(accepted,active,handled,reading,total,waiting,writing)

nginx_error_log

APIcast 错误

计数

level(debug,info,notice,warn,error,crit,alert,emerg)

openresty_shdict_capacity

worker 共享字典的能力

gauge

dict(每个字典对应一个)

openresty_shdict_free_space

worker 共享字典的可用空间

gauge

dict(每个字典对应一个)

nginx_metric_errors_total

管理指标的 Lua 库错误数

计数

none

total_response_time_seconds

向客户端发送响应所需的时间(以秒为单位)

: 要访问 service_idservice_system_name 标签,您必须将 APICAST_EXTENDED_METRICS 环境变量设置为 true,如 第 9.2 节 “APIcast 与 Prometheus 集成” 所述。

histogram

service_id,service_system_name

upstream_response_time_seconds

来自上游服务器的响应时间(以秒为单位)

: 要访问 service_idservice_system_name 标签,您必须将 APICAST_EXTENDED_METRICS 环境变量设置为 true,如 第 9.2 节 “APIcast 与 Prometheus 集成” 所述。

histogram

service_id,service_system_name

upstream_status

来自上游服务器的 HTTP 状态

: 要访问 service_idservice_system_name 标签,您必须将 APICAST_EXTENDED_METRICS 环境变量设置为 true,如 第 9.2 节 “APIcast 与 Prometheus 集成” 所述。

计数

status, service_id, service_system_name

threescale_backend_calls

授权并报告请求到 3scale 后端(Apisonator)

计数

endpoint(authrep, auth, report), status(2xx, 4xx, 5xx)

表 9.3. 3scale APIcast 批处理策略的 Prometheus Metrics

指标描述类型标签

batching_policy_auths_cache_hits

按 3scale 批处理策略的 auths 缓存中的内容

计数

none

batching_policy_auths_cache_misses

3scale 批处理策略的 auths 缓存中丢失

计数

none

部分 II. API 版本控制

第 10 章 API 版本

红帽 3scale API 管理允许 API 版本控制。当您使用 3scale 管理 API 时,可以通过三种方法正确发布 API:以下是您可以在 3scale 网关中对 API 进行版本的示例,它根据 3scale 架构提供了额外的功能。

10.1. 目标

本指南旨在为您提供足够信息,以便在 3scale 中实施 API 版本系统。

假设您有一个用于查找歌曲的 API。用户可以通过不同的关键字搜索自己喜欢的歌曲:艺术家、歌曲、歌曲标题、相簿标题等等。假设您有 API 的初始版本(v1),现在您已开发了一个新的改进版本(v2)。

以下小节介绍了使用 3scale 实施 API 版本系统的三种最典型的方法:

  • URL 版本
  • 端点版本控制
  • 自定义标头版本

10.2. 先决条件

在使用此快速启动指南之前,完成将 API 连接到 3scale 的 基础知识。

10.3. URL 版本

如果您具有不同的用于搜索歌曲的端点(通过工件,按歌曲标题等),使用 URL 版本作为 URI 的一部分包括 API 版本,例如:

  1. api.songs.com/v1/songwriter
  2. api.songs.com/v2/songwriter
  3. api.songs.com/v1/song
  4. api.songs.com/v2/song
  5. 以此类推
注意

使用此方法时,自 v1 准备对 API 进行版本之后,您应已进行了规划。

然后,3scale 网关将从 URI 中提取端点和版本。这种方法允许您为任何版本/端点组合设置应用计划。然后,您可以将指标与这些计划和端点关联,您可以绘制各个版本上每个端点的使用情况。

以下屏幕截图显示了 3scale 的灵活性。

图 10.1. 版本计划功能

版本计划功能

唯一需要做的是进入 3scale 管理门户中的 [your_API_name] > Integration > Configuration,并将您的 URI 映射到您的指标,如下图所示。

图 10.2. 将 URI 映射到指标

将 URI 映射到指标

您现在有两个不同的 API 版本,各自启用了不同的功能。您对它们的使用具有完全的控制权和可见性。

如果您要与应移至 API v2 的所有用户通信,您可以发送内部备注要求他们这样做。您可以监控谁进行了移动,并了解 v1 上的活动在 v2 活动增加期间如何减少。通过在授权调用中向 3scale 添加指标,您可以看到整体流量到达 v1 与 v2 端点,并了解何时可以安全地弃用 v1。

图 10.3. 版本控制

版本控制

如果某些用户使用 v1,则只能过滤出那些用户,以发送有关切换到 v2 的另一个内部备注。

3scale 提供三步方法来发送弃用通知。

  1. 导航到 Audience > Applications > Listing,并根据您要发送弃用备注的应用程序计划过滤列表并点击 Search
  2. 单击 multiselector,以选择该特定版本的所有应用。显示新的选项,并允许您执行批量操作,如 发送电子邮件更改应用程序计划更改状态
  3. Send email,然后按照步骤将弃用通知发送到所选应用程序的所有者。

下图提供了一个可视化参考。

图 10.4. 发送弃用备注

发送弃用备注

对于对端点发出的每个 authrep 调用,您仅进行身份验证一次,但为端点报告两次,一次报告一次用于 API 版本。没有可重复性,因为调用只能一次被验证。对于您对特定 API 版本的任何端点进行的调用,您可以将点击聚合到以版本号(v1、v2 等)命名的方便指标上,您可以使用它来相互比较完整的版本流量。

10.4. 端点版本控制

通过端点版本控制,您可以为每个 API 版本使用不同的端点,如 api.cons.com/author_v1。网关从端点本身提取端点和版本。此方法以及上述方法允许 API 提供程序将外部 URL 映射到内部 URL。

端点版本方法只能通过内部部署方法执行,因为它需要使用作为内部配置一部分提供的 LUA 脚本来重写 URL。

EXTERNAL

 

INTERNAL

api.songs.com/songwriter_v1

可被重写为

internal.songs.com/search_by_songwriter

api.songs.com/songwriter_v2

可被重写为

internal.songs.com/songwriter

几乎所有(映射、应用程序计划功能等)的工作方式都与之前的方法完全相同。

10.5. 自定义标头版本

使用自定义标头版本控制时,您可以使用标头(即 "x-api-version")而不是 URI 来指定版本。

然后,网关从该路径和标头中提取端点。就像以前一样,您可以分析和视觉化任何您想要的路径/版本组合。这种方法存在一些不便,无论您使用的 API 管理系统是什么。如需了解更多信息,请参阅 API 版本方法。以下是 3scale 工作原理的几个要点:

  • 与前面的方法一样,自定义标头版本控制只能应用到内部托管 API,因为它需要一些请求标头解析/处理才能正确路由 authrep 调用。这种类型的自定义处理只能通过 Lua 脚本进行。
  • 使用此方法时,很难实现之前方法的细粒度功能分隔。
  • 这种方法最重要的优势在于,开发人员指定的 URL 和端点永远不会更改。当开发人员希望从一个 API 版本切换到另一个 API 版本时,他们只需要更改标头。其他所有功能都相同。

部分 III. API 身份验证

第 11 章 身份验证模式

在本教程结束时,您将了解如何在 API 上设置身份验证模式,以及对应用程序与 API 通信的影响。

根据您的 API,您可能需要使用不同的身份验证模式来发布凭据以访问您的 API。它们可以从 API 密钥到 openAuth 令牌和自定义配置。本教程介绍了如何从可用的标准身份验证模式中进行选择。

11.1. 支持的验证模式

3scale 支持以下开箱即用的身份验证模式:

  • 标准 API 密钥 :单一随机字符串或哈希值作为标识符和 secret 令牌。
  • 应用程序标识符和键对:可以识别 识别符和可可变的 secret 密钥字符串。
  • OpenID Connect

11.2. 设置身份验证模式

11.2.1. 选择服务的验证模式

导航到您要处理的 API 服务(在这种情况下,可能只有一个名为 API 的服务)。前往 Integration 部分。

选择"验证模式"第 1 步

您运行的每个服务都可以使用不同的身份验证模式,但每个服务只能使用一种模式。

重要

在注册了凭证后,您不得更改身份验证模式,因为服务的行为可能会变得无法预测。要更改身份验证模式,我们建议创建新服务并迁移客户。

11.2.2. 选择要使用的 Authentication 模式

若要选择身份验证模式,可滚动到 AUTHENTICATION 部分。在这里,您可以选择以下选项之一:

  • API 密钥(user_key)
  • App_ID 和 App_Key Pair
  • OpenID Connect

11.2.3. 确保您的 API 接受正确类型的凭证

根据所选的凭证类型,您可能需要接受 API 调用中的不同参数(密钥字段、ID 等)。这些参数的名称可能与 3scale 中内部使用的参数不同。如果在 3scale 后端调用中使用了正确的参数名称,3scale 身份验证将正确运行。

11.2.4. 创建用于测试凭证的应用程序

为确保凭据集正常工作,您可以创建一个新应用来签发凭据以使用 API。导航到管理门户控制面板的 Accounts 区域,单击要使用的帐户,再单击 新应用程序

填写表单并单击 save 将创建一个包含凭据的新应用,以使用 API。现在,您可以使用这些凭证来调用 API,并且会根据 3scale 中注册的应用程序列表检查记录。

11.3. 标准验证模式

3scale 支持以下部分中详述的身份验证模式。

11.3.1. API 密钥

支持最简单的凭证形式是单一 API 模型。在这里,每个具有 API 权限的应用程序都有单个(唯一)长字符串;例如:

API-key = 853a76f7c8d5f4a1ee8bf10a4e0d1f13

默认情况下,key 参数的名称是 user_key。您可以使用该标签或选择另一个标签,如 API-key。如果选择其他标签,则需要在向 3scale 发出授权调用前映射该值。字符串同时充当标识符和机密令牌,供 API 使用。建议您仅在安全要求低或 API 调用的 SSL 安全性的环境中使用这些模式。以下是可以在令牌和应用程序上执行的操作:

  • Application Suspend:这会挂起应用程序对 API 的访问,并无效,所有对带有相关密钥的 API 的调用将被暂停。
  • 应用程序恢复:取消应用暂停操作的效果。
  • key Regenerate:此操作为应用程序生成一个新的随机字符串键,并将其与应用程序相关联。立即执行此操作后,对前一个令牌的调用将不再被接受。

后一操作可以从管理门户中的 API 管理以及(如果允许)从 API Developers 用户控制台触发。

11.3.2. App_ID 和 App_Key 对

API Key Pattern 将应用程序的身份和 secret 用量令牌组合在一个令牌中,但这种模式将两者分开:

  • 使用 API 的每个应用都发出不可变的初始标识符,称为 应用 ID(App ID)。App ID 是恒定的,不一定是保密的。
  • 此外,每个应用程序都可以有一到五个 应用密钥 (App_Keys)。每个密钥都直接与 App_ID 关联,应视为机密。
app_id = 80a4e03 app_key = a1ee8bf10a4e0d1f13853a76f7c8d5f4

在默认设置中,开发人员可以为每个应用创建最多五个密钥。这允许开发人员创建新密钥,将它添加到代码中,重新部署其应用,然后禁用旧密钥。这不会以 API 密钥重新生成的方式造成应用程序停机。

统计信息和速率限值始终保持在应用程序 ID 的粒度级别,而不是每个 API 密钥。如果开发人员希望跟踪两组统计数据,他们应创建两个应用,而不是两个键。

也可以更改系统上的模式,并允许在没有应用密钥的情况下创建应用程序。在这种情况下,3scale 系统将仅根据 App ID 验证访问权限(不进行密钥检查)。此模式可用于小部件类型场景,或者对用户而非应用程序应用速率限制。在大多数情况下,您可能希望 API 强制每个应用程序存在至少一个应用程序密钥。此设置包括在 [your_API_name] > Integration > Settings 中。

11.3.3. OpenID Connect

有关 OpenID Connect 身份验证的详情,请查看 OpenID Connect 集成 章节。

11.4. 参考器过滤

3scale 支持转译器过滤器功能,可用于将应用程序可以访问 API 的 IP 地址或域名列入白名单。API 客户端在 Referrer 标头中指定 referrer 值。RFC 7231 节第 5.5.2 节中描述参考器标头的用途和使用。2请参阅

要启用 引用器过滤功能进入 [your_API_name] > Integration > Settings,点 Require referrer 过滤 复选框并点 Update Service

启用推荐程序过滤器

有权访问您的 API 的开发人员必须配置开发人员门户允许的域/IP 引用器。

在 Developer Portal 中配置推荐

在 Admin Portal on the application details 页中,所有属于该服务的应用程序详情页面中会显示一个新的 Referencerer Filters 部分。此处,管理员也可以为此应用程序配置允许参考器标头值的白名单。

在 Developer Portal 中配置推荐

您可以为每个应用程序设置最多五个引用者值。

该值只能包含拉字母、数字和特殊字符 *.-* 可用于通配符值。如果值设为 *,则允许任何引用器值,因此将绕过引用器检查。

要使 Rerer Filtering 功能正常工作,您必须在服务策略链中启用 APIcast Referrer policy

Require referrer 过滤 功能和 3scale Referencerer 策略 被启用时,授权会按以下方式工作:

  1. 没有指定推荐过滤器的应用程序通常只使用提供的凭证获得授权。
  2. 对于设置有引用器过滤器值的应用程序,APIcast 从请求的引用者标头中提取 引用器 值,并将它作为 AuthRep(授权和报告)请求中的 引用器 param 发送到 Service Management API。下表显示了针对引用器过滤参数的不同组合的 AuthRep 响应。
referrer 参数通过?为应用配置了参考器过滤器?引用器参数值HTTP 响应响应正文

匹配引用器过滤器

200 OK

<status><authorized>true</authorized></status>

匹配引用器过滤器

200 OK

<status><authorized>true</authorized></status>

不匹配引用器过滤器

409 冲突

<status><authorized>false</authorized><reason>referrer "test.example.com" is not allowed</reason> (test.example.com 是一个示例)

不匹配引用器过滤器

200 OK

<status><authorized>true</authorized></status>

*

200 OK

<status><authorized>true</authorized></status>

*

200 OK

<status><authorized>true</authorized></status>

 — 

409 冲突

<status><authorized>false</authorized><reason>referrer is missing</reason>

 — 

200 OK

<status><authorized>true</authorized></status>

未经 AuthRep 授权的调用将被 APIcast 拒绝,并显示"Authorization Failed"错误。您可以在服务集成页面上配置确切的状态代码和错误消息。

第 12 章 OpenID Connect 集成

3scale 与第三方身份提供程序(IdP)集成,用于使用 OpenID Connect 规格验证 API 请求,包括以下功能:

  • OpenID Connect 基于 OAuth 2.0 基础上构建,通过身份验证机制补充 OAuth 2.0 授权框架。
  • 使用 OpenID Connect 身份验证 选项时,API 请求使用 JSON Web Token(JWT)格式(RFC 7519)格式的访问令牌进行身份验证。

集成由以下两个部分组成:

红帽 3scale API 管理完全支持两个集成点作为 OpenID 提供程序的红帽单点登录(RH-SSO)。请参阅 支持的 Configurations 页面中的 RH-SSO 版本。APIcast 集成也通过 ForgeRock 进行测试。

在这两种情况下,您可以使用 OpenID Connect 身份验证选项在服务的 Integration 页面上指定 OpenID Connect Issuer 字段来配置集成。具体步骤请参阅 配置 Red Hat Single Sign-On 集成

12.1. APIcast 验证和解析 JWT

使用 OpenID Connect 身份验证模式对服务的 API 请求应当通过 Bearer 模式在 Authorization 标头中以 JWT 格式提供访问令牌。标头应类似以下示例:

Authorization: Bearer <JWK>

例如:

Authorization: Bearer: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLmNvbSIsInN1YiI6ImFiYzEyMyIsIm5iZiI6MTUzNzg5MjQ5NCwiZXhwIjoxNTM3ODk2MDk0LCJpYXQiOjE1Mzc4OTI0OTQsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiQmVhcmVyIn0.LM2PSmQ0k8mR7eDS_Z8iRdGta-Ea-pJRrf4C6bAiKz-Nzhxpm7fF7oV3BOipFmimwkQ_-mw3kN--oOc3vU1RE4FTCQGbzO1SAWHOZqG5ZUx5ugaASY-hUHIohy6PC7dQl0e2NlAeqqg4MuZtEwrpESJW-VnGdljrAS0HsXzd6nENM0Z_ofo4ZdTKvIKsk2KrdyVBOcjgVjYongtppR0cw30FwnpqfeCkuATeINN5OKHXOibRA24pQyIF1s81nnmxLnjnVbu24SFE34aMGRXYzs4icMI8sK65eKxbvwV3PIG3mM0C4ilZPO26doP0YrLfVwFcqEirmENUAcHXz7NuvA

JWT 令牌包含一个签名,令牌的接收方可以验证和确保令牌由已知签发者签名,并且其内容尚未更改。3scale 支持基于公钥/私钥对的 RSA 签名。此处,签发者使用私钥签署 JWT 令牌。APIcast 会使用公钥验证此令牌。

APIcast 使用 OpenID Connect Discovery 获取可用于验证 JWT 签名的 JSON Web 密钥(JWK)。

每个请求上,APIcast 执行以下操作:使用公钥验证 JWT 令牌。验证声明 nbfexp。验证声明中指定的签发者 是否为 (Issuer)是否与 OpenID Connect Issuer 字段中配置的相同。提取 azpaud 声明的值,并将其用作客户端 ID,以标识 3scale 中的应用程序,以通过 Service Management API 授权调用。

如果任何 JWT 验证或授权检查失败,APIcast 会返回"Authenication failed" 错误。否则,APIcast 将请求代理到 API 后端。Authorization 标头保留在请求中,因此 API 后端也可以使用 JWT 令牌来检查用户和客户端身份。

12.2. 由 zync-que同步客户端凭证

当您使用 zync-que 组件时,3scale 会在 3scale 和 RH-SSO 服务器之间同步客户端(应用程序)凭据。通过 OpenID Connect Issuer 设置进行配置。

当您创建、更新或删除配置为使用 OpenID Connect, zync-que 的服务时,会接收相应的事件,并使用 RH-SSO API 向 RH-SSO 实例传达更改。

Configure Red Hat Single Sign-On 集成 部分提供了确保 zync-que 具有使用 RH-SSO API 的正确凭据所需的步骤。

12.3. 配置红帽单点登录集成

以下流程逐步指导您配置 zync-que 以使用自定义 CA 证书。

12.3.1. 配置 zync-que 以使用自定义 CA 证书

先决条件

  • 您必须能够通过 https 提供 RH-SSO,并确保它可通过 by zync-que 访问。要测试此类型,请执行以下操作:

    curl https://rhsso-fqdn
  • 3scale 2.2 和更高版本支持带有 SSL_CERT_FILE 环境变量的 RH-SSO 的自定义 CA 证书。此变量指向证书捆绑包的本地路径。
注意
  • 些版本的 OpenSSL 接受 -showcerts 而不是 --showcerts。将以下命令相应地修改为正在使用的版本:
  • 以下流程步骤 1 中的命令涉及 <rhsso_fqdn>。完全限定域名(FQDN)是人类可读的域名,如 host.example.com

流程

  1. 运行以下命令获取正确的证书链:

    echo -n | openssl s_client -connect <rhsso_fqdn>:<rhsso_port> -servername <rhsso_fqdn> --showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > customCA.pem

流程

  1. 使用以下 cURL 命令验证新证书:预期响应是 域的 JSON 配置。如果验证失败,这表示您的证书可能不正确。

    curl -v https://<secure-sso-host>/auth/realms/master --cacert customCA.pem
  2. 将证书捆绑包添加到 Zync pod:

    1. 收集 Zync pod 上 /etc/pki/tls/cert.pem 文件的现有内容。运行:

      oc exec <zync-que-pod-id> cat /etc/pki/tls/cert.pem > zync.pem
    2. 附加自定义 CA 证书文件的内容 to zync.pem

      cat customCA.pem >> zync.pem
    3. 将新文件作为 ConfigMap 附加到 Zync pod:

      oc create configmap zync-ca-bundle --from-file=./zync.pem
      oc set volume dc/zync-que --add --name=zync-ca-bundle --mount-path /etc/pki/tls/zync/zync.pem --sub-path zync.pem --source='{"configMap":{"name":"zync-ca-bundle","items":[{"key":"zync.pem","path":"zync.pem"}]}}'
  3. 部署后,验证证书是否已附加,内容是否正确:

    oc exec <zync-pod-id> cat /etc/pki/tls/zync/zync.pem
  4. 在 Zync 上配置 SSL_CERT_FILE 环境变量以指向新的 CA 证书捆绑包:

    oc set env dc/zync-que SSL_CERT_FILE=/etc/pki/tls/zync/zync.pem

12.3.2. 配置红帽单点登录

要配置 RH-SSO,请执行以下步骤:

  1. 创建一个域(<realm_name>)。
  2. 创建客户端:

    1. 指定客户端 ID。
    2. Client Protocol 字段中,选择 openid-connect
  3. 要配置客户端权限,请设置以下值:

    1. Access Typeconfidential
    2. Standard Flow EnabledOFF
    3. Direct Access Grants EnabledOFF
    4. Service Accounts EnabledON
  4. 为客户端设置服务帐户角色:

    1. 导航到客户端的 Service Account Roles 选项卡。
    2. 客户端角色 下拉列表中,单击 realm-management
    3. Available Roles 窗格中,选择 manage-clients 列表项,并通过点 Add selected >> 来分配角色。
  5. 请注意客户端凭证:

    1. 记录客户端 ID(<client_id>)。
    2. 导航到客户端的 Credentials 选项卡,并记录 Secret 字段(<client_secret>)。
  6. 在域中添加用户:

    1. 单击窗口左侧的 Users 菜单。
    2. 单击 Add user
    3. 键入用户名,将 Email Verified 开关设置为 ON,然后单击 Save
    4. Credentials 选项卡上,设置密码。在两个字段中输入密码,将 Temporary 开关设置为 OFF,以避免在下次登录时重置密码,然后单击 Reset Password
    5. 显示弹出窗口时,单击 Change password

12.3.3. 配置 3scale

在 RH-SSO 中创建并配置了客户端后,您必须配置 3scale 以使用 RH-SSO。

要配置 3scale,请执行以下步骤:

  1. 启用 OpenID Connect。

    1. 选择您要启用 OpenID Connect 身份验证的服务,进入 [your_API_name] > Integration > Configuration
    2. 选择 编辑集成设置
    3. Authentication 部署选项下,选择 OpenID Connect
    4. Update Service 保存设置。
  2. 编辑 APIcast 配置:

    1. 进入 [your_API_name] > Integration > Configuration
    2. 选择 edit APIcast configuration
    3. Authentication Settings 标题下,在 OpenID Connect Issuer 字段中输入之前记录的、带有 RH-SSO 服务器的 URL(位于主机 <rhsso_host> 和端口 <rhsso_ port >)的客户端凭证。

      https://<client_id>:<client_secret>@<rhsso_host>:<rhsso_port>/auth/realms/<realm_name>
    4. 要保存配置,请单击 Update the Staging Environment

12.4. 配置与第三方身份提供程序的 HTTP 集成

您可以配置 OpenID Connect(OIDC)的 HTTP 集成,以便于与第三方身份提供程序(IdP)同步凭证。这意味着,通过实施我们提供的 OpenAPI 规格,可以集成 RH-SSO 以外的不同的 IdP。

12.4.1. 先决条件

  • * 启用 OIDC 作为验证模式,如 Configure 3scale所示
  • Zync
  • 与 Zync 集成,实现所选 IdP 和 3scale 之间的客户端同步

12.4.2. 流程

要配置 OIDC 与第三方身份提供程序的 HTTP 集成,请在管理门户中按照以下步骤执行:

  1. 进入 [Your_API_name] > Integration > edit APIcast configuration > Authentication Settings
  2. OpenID Connect Issuer Type 下,选择 REST API
  3. OpenID Connect Issuer 中,指定 OpenID Provider 的位置。
  4. 要保存更改,请点击 Update the Staging Environment

12.4.3. Zync REST API 示例

这个示例项目实施 Zync REST API 协议来同步 OAuth2.0 客户端。在创建 3scale 应用程序时,更新或删除 Zync 会尝试将该更改复制到 http://example.com/api

12.4.3.1. 先决条件

3scale 必须配置为使用:

  • OIDC 作为身份验证模式
  • REST API 作为 OpenID Connect Issuer 类型
  • http://id:secret@example.com/api as OpenID Connect Issuer

12.4.3.2. 创建、更新和删除客户端

Zync 发出以下请求来创建、更新或删除客户端:* 创建和更新 → PUT /clients/:client_id * Delete → DELETE /clients/:client_id

所有端点必须以 2xx 状态代码进行回复。否则,3scale 会重试请求。

12.4.3.3. payload

创建和更新时的请求有效负载为 application/json

{
  "client_id": "ee305610",
  "client_secret": "ac0e42db426b4377096c6590e2b06aed",
  "client_name": "oidc-app",
  "redirect_uris": ["http://example.com"],
  "grant_types": ["client_credentials", "password"]
}

删除客户端的请求没有有效负载。

12.4.3.4. 使用 OAuth2 身份验证

Zync 将 GET 请求发送到 /.well-known/openid-configuration 端点,并且需要一个 application/json 响应。响应有效负载应包含以下内容:

{
  "token_endpoint": "http://idp.example.com/auth/realm/token"
}

Zync 使用 token_endpoint 来交换使用 OAuth2 协议的 OpenID Connect Issuer 地址中提供的 client_idclient_secret。如果 API 响应失败的响应,则 Zync 回退到使用提供的凭证的 HTTP Basic/Digest 身份验证。

12.5. OAuth 2.0 支持的流

API 客户端必须使用此 OpenID 提供程序支持的任何 OAuth 2.0 流从 3scale 中配置的 OpenID Connect(OIDC)签发者获取访问令牌。对于 RH-SSO,则支持以下流(RH-SSO 客户端中使用的术语在括号中):

  • Authorization Code (Standard Flow)
  • 资源所有者密码凭证(直接访问授予流
  • Implicit (Implicit Flow)
  • Client Credentials (Service Accounts Flow)

当在 3scale 中创建 OpenID Connect(OIDC)中的客户端时,Red Hat Single Sign-On(RH SSO)中由 Zync 创建的对应客户端仅启用了 Authorization Code 流。建议将此流程作为最适合大多数情况的最安全和最合适的流程。不过,也可以启用其他流。

12.5.1. OAuth 2.0 支持的流的工作方式

客户端使用授权请求或令牌请求获取访问令牌,或两者。接收这些请求的 URL 可以在相应 "authorization_endpoint""token_endpoint" 的 OpenID 提供程序的 .well-known/openid-configuration 端点中发现。示例: https://<RHSSO_HOST>:<RHSSO_PORT>/auth/realms/<REALM_NAME>/.well-known/openid-configuration.

12.5.2. 配置 OAuth 2.0 支持的流

您可以在管理门户中为 3scale API 配置允许的 OAuth 2.0 流。当您创建新应用程序时,基本集成已完成,包括 OpenId Connect(OIDC)配置。

要配置 OAuth 2.0 支持的流,请执行以下步骤:

  1. 进入 Authentication Settings 部分: [Your_API_name] > Integration > edit integration settings > Authentication
  2. 选择 OpenId Connect
  3. 在 RH SSO 端的客户端上启用了对应的流。您可以通过浏览 [Your_API_name] > Integration > Edit APIcast configuration > Authentication Settings来查看它们

    • standardFlowEnabled (身份验证代码流)[默认选择]
    • hiddenFlowEnabled (Implicit 流)
    • ServiceAccountsEnabled (服务帐户流)
    • directAccessGrantsEnabled (直接访问授予流)
  4. 选择一个或多个流。
  5. 要保存更改,请点击 Update the Staging Environment

12.6. 测试集成

要测试集成,您必须执行以下部分中列出的步骤。

12.6.1. 测试客户端同步

要测试客户端同步,请执行以下步骤:

  1. 为配置了 OpenID Connect 集成的服务创建一个应用。
  2. 注意生成的应用的客户端 ID 和客户端 Secret。
  3. 验证配置的 RH-SSO 域中现在是否存在具有相同客户端 ID 和客户端 secret 的客户端。
  4. 在 3scale 管理门户中更新应用的重定向 URL。重定向 URL 应尽量具体。
  5. 验证 RH-SSO 中客户端的 Valid Redirect URIs 字段是否已相应地更新。

12.6.2. 测试 API 授权流

要测试 APT 授权流,请执行以下步骤:

  1. 使用对应的 RH-SSO 客户端上启用的 OAuth 2.0 流从 RH-SSO 服务器获取访问令牌。
  2. 使用 Authorization 标头中从 RH-SSO 检索的 access_token 的值,如下所示: Authorization: Bearer <access_token>

如果令牌正确并且 3scale 中的对应应用程序被授权,APIcast 网关会返回来自 3scale 后端的响应。

12.7. 集成示例

3scale 中的服务 API 被配置为使用 OpenID Connect 身份验证。服务 API 上的 公共基本 URL 配置为 https://api.example.com专用基本 URL 配置为 https://internal-api.example.com

OpenID Connect Issuer 字段在 API 集成中被设置为 https://zync:/auth/realms/myrealm,而 realm myrealm 中的客户端 zync 具有正确的服务帐户角色。

3scale 中有一个具有 myclientid 客户端 ID、myclientsecret 客户端 secret 和 https://myapp.example.com 重定向 URL 的应用。

在 RH-SSO 域中,myrealm 域中也存在具有这些值的客户端:

  • 客户端 ID: myclientid
  • Secret: myclientsecret
  • 有效的 Redirect URIs:https://myapp.example.com

对于这个客户端,启用标准流。myrealm 域中配置了具有 myuser 用户名和 mypassword 密码的用户。

流程如下:

  1. 使用端点 https://idp.example.com/auth/realms/myrealm/protocol/openid-connect/auth,应用向 RH-SSO 发送授权请求。在请求中,应用程序提供了这些参数: myclientid 客户端 ID 和 https://myapp.example.com 重定向 URL。
  2. RH-SSO 显示登录窗口,其中用户必须提供用户的凭据:Username myuser 和密码 mypassword
  3. 根据配置,如果这是用户首次在此特定应用中进行身份验证,则将显示同意窗口。
  4. 用户进行身份验证后,应用会使用端点 https://idp.example.com/auth/realms/myrealm/protocol/openid-connect/token 向 RH-SSO 发送令牌请求,并提供客户端 ID myclientid、客户端 secret myclientsecret 和 Redirect URL https://myapp.example.com
  5. RH-SSO 返回带有 "access_token" 字段 eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArqF-A 的 JSON。
  6. 应用程序向 https://api.example.com 发送 API 请求到带有标头 Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArqF-A
  7. 应用程序应该从 https://internal-api.example.com 收到成功的响应。