Menu Close

管理 API 网关

Red Hat 3scale API Management 2.11

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

摘要

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

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看我们的 CTO Chris Wright 信息

管理 API 网关可帮助您将高级配置功能应用到 3scale 安装。有关安装的基本详情,请参阅安装 3scale。

部分 I. API 网关

第 1 章 3scale APIcast API 网关的高级操作简介

3scale APIcast 的高级操作将帮助您调整对 API 的访问配置。

1.1. 用于调用 3scale API 的公共基本 URL

公共基本 URL 是您的 API 客户用来向 API 产品发出请求的 URL,该产品可通过 3scale 公开。这将是您的 APIcast 实例的 URL。

如果您使用自助管理部署选项之一,您可以在您管理的域名上为提供的每个环境(登台和生产)选择自己的公共基本 URL。这个 URL 应该与您 API 后端的 URL 不同,可能类似 https://api.yourdomain.com:443,其中 yourdomain.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=you_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. APIcast 如何应用映射规则来捕获 3scale API 的使用

根据对 API 的请求,映射规则定义指标或指定您要捕获 API 使用情况的方法。以下是映射规则的示例:

映射规则

此规则意味着,任何以 / 开头的 GET 请求都以 1 为指标 hits 的增量。此规则匹配到您的 API 的任何请求。虽然这是有效的映射规则,但它太通用,如果您添加了更具体的映射规则,则通常会导致被双倍计数。

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

Hello World 映射规则

映射规则在 API 产品和 API 后端级别上工作。

  • 在产品级别上映射规则。

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

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

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

以下示例显示了一个后端产品的映射规则。

现在,假设有一个名为 Tools For Devs 的其他产品,它使用相同的 Echo API 后端。

映射规则的匹配

3scale 根据前缀应用映射规则。表示法遵循 OpenAPI 和 ActiveDocs 规格:

  • 映射规则必须以正斜杠(/)开头。
  • 在路径上对文字字符串执行匹配,即 URL,例如 /hello

    • 映射规则保存后,将导致请求发送到您已设置的 URL 字符串,并调用您围绕每个映射规则定义的指标或方法。
  • 映射规则可以在查询字符串或正文中包含参数,例如 /{word}?value={value}
  • APIcast 获取参数的方式如下:

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

映射规则工作流

映射规则有以下工作流:

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

停止其他映射规则

在处理一个或多个映射规则后,若要停止处理其他映射规则,请在创建新的映射规则时选择 Last?。例如,假设 API 集成设置 中定义了以下映射规则,并且每个规则都有不同的指标:

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

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

1.3. APIcast 如何处理具有自定义要求的 API

有些特殊情形需要自定义 APIcast 配置,以便 API 用户能够成功调用 API。

主机标头

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

要避免这个问题,您可以在 Authentication Settings:[Your_product_name] > Integration > SettingsHost Header 字段中定义 API 产品所需的主机

其结果是托管 APIcast 实例会在请求调用中重写主机规格。

主机重写

保护 API 后端

在 APIcast 在生产环境中工作后,您可能希望将直接访问 API 产品限制为仅那些指定您指定的 secret 令牌的调用。为此,请设置 APIcast Secret Token。如需有关如何设置它的信息,请参阅 高级 APIcast 配置

将 APIcast 与私有 API 搭配使用

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

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

    在这种情况下,您可以在 Private Base URL 字段中设置您的内部域名或 API 的 IP 地址,并照常执行其余步骤。但是,执行此操作意味着您无法利用暂存环境。测试调用将无法成功,因为暂存 APIcast 实例由 3scale 托管,无法访问您的私有 API 后端。在生产环境中部署 APIcast 后,如果配置正确,APIcast 可以按预期工作。

1.4. 将 APIcast 配置为使用 OpenTracing

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

先决条件

  • 每个外部请求必须附加有一个唯一的请求 ID。这通常在 HTTP 标头中。
  • 每个服务都必须将请求 ID 转发到其他服务。
  • 每一服务必须在日志中输出请求 ID。
  • 每个服务必须记录其他信息,如请求的开始和结束时间。
  • 日志必须聚合,并提供一种通过 HTTP 请求 ID 解析日志的方法。

步骤

  1. 确保 OPENTRACING_TRACER 环境变量设置为 jaeger。如果这是空的,则禁用 OpenTracing。
  2. 设置 OPENTRACING_CONFIG 环境变量,以指定 tracer 的默认配置文件。请参阅以下示例 jaeger.example.json 文件。
  3. 可选:根据您的 OpenTracing 配置设置 OPENTRACING_HEADER_FORWARD 环境变量。

验证

要测试集成是否正常工作,请检查 Jaeger 追踪接口中是否报告 trace。

1.5. 在 OpenShift 实例上安装 Jaeger

3scale API 供应商可以使用 Jaeger 的 OpenTracing 来跟踪和排除对 API 的调用和故障排除。为此,请在运行 3scale 的 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
        }
     }
    • sampler 常数 1 表示您想要对所有请求进行抽样。
    • reporter 的位置和队列大小是必需的。
    • headers 下,需要 TraceContextHeaderName 条目来跟踪请求
  3. 从 Jaeger 配置文件创建 ConfigMap,并将其挂载到 APIcast:

    oc create configmap jaeger-config --from-file=jaeger_config.json
    oc set volumes 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. 在后端 API 中添加 OpenTracing 和 Jaeger 支持,以便您可以查看完整的请求追踪。根据所用的框架和语言,每个后端都有所不同。作为参考,请参阅在 Kubernetes 中使用 OpenTracing 和 Jaeger 来收集应用程序指标

第 2 章 操作 Docker 容器化环境

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

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

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

docker:Cannot connect to the Docker daemon.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 请求时会出现这种情况。
  • 无匹配项:此错误意味着请求与任何映射规则不匹配,因此没有更新指标。这不一定是错误,但意味着用户正在尝试随机路径,或者您的映射规则无法涵盖合法情况。
  • 超过用量限制:此错误意味着客户端达到所请求端点的速率限值。如果请求与多个映射规则匹配,客户端可能会达到多个速率限制。

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

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

    • 响应代码:HTTP 响应代码。
    • Content-type:Content-Type 标头的值。
    • 响应正文:响应消息正文的值。
  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_1word 的 hit 增加 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 策略的信息。

4.1. 用于更改默认 3scale APIcast 行为的标准策略

3scale 提供内置的标准策略,它们是修改 APIcast 处理请求和响应的方式的功能单元。您可以启用、禁用或配置策略来控制它们如何修改 APIcast。

详情请参阅 在 3scale 管理门户中启用策略。3scale 提供以下标准策略:

4.1.1. 在 3scale 管理门户中启用策略

在管理门户中,您可以为每个 3scale API 产品启用一个或多个策略。

先决条件

  • 3scale API 产品

步骤

  1. 登录 3scale。
  2. 在管理门户控制面板中,选择要为其启用策略的 API 产品。
  3. [your_product_name],进入到 Integration > Policies
  4. 在 POLIC IES 部分下,单击 Add policy
  5. 选择您要添加的策略,并在任何必填字段中输入值。
  6. 单击 Update Policy Chain 以保存策略链。

4.1.2. 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.3. 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 后端来检索授权状态。
    • auths_ttl 参数设置为 0 以外的值。将 auths_ttl 设置为 0 的值可在第一次缓存请求时更新授权计数器,从而导致速率限制无效。
  • batch_report_seconds:设置批处理报告 APIcast 发送到 3scale 后端的频率。默认值为 10 秒。
重要

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

4.1.4. 3scale Referrer

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

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

4.1.5. Anonymous Access(匿名访问)

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

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

注意

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

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

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

    • app_id_and_app_key:应用程序 ID/应用程序密钥身份验证选项:
    • user_key:用于 API 密钥身份验证选项。
  • app_id (仅适用于 app_id_and_app_key 身份验证类型):API 调用中未提供任何凭据时将用于授权的应用的 App Id。
  • app_key (仅适用于 app_id_and_app_key 身份验证类型):API 调用中不提供任何凭据时将用于授权的应用的 App Key。
  • user_key (仅适用于 user_key auth_type):API 调用中不提供任何凭据时将用于授权的应用的 API 密钥。

图 4.1. 匿名访问策略

匿名访问策略

4.1.6. Camel Service

您可以使用 Camel 服务策略定义 HTTP 代理,该代理通过定义的 Apache Camel 代理发送 3scale 流量。在这种情况下,Camel 充当反向 HTTP 代理,APIcast 将流量发送到 Camel,然后 Camel 会将流量发送到 API 后端。

以下示例显示了流量流:

Camel 服务策略请求流

发送到 3scale 后端的所有 APIcast 流量都不使用 Camel 代理。此策略仅适用于 Camel 代理以及 APIcast 和 API 后端之间的通信。

如果要通过代理发送所有流量,则必须使用 HTTP_PROXY 环境变量。

注意
  • Camel 服务策略禁用所有负载平衡策略,流量发送到 Camel 代理。
  • 如果定义了 HTTP_PROXYHTTPS_PROXYALL_PROXY 参数,此策略将覆盖这些值。
  • 代理连接不支持身份验证。您可以使用标头修改策略进行身份验证。

Configuration

以下示例显示了策略链配置:

"policy_chain": [
    {
      "name": "apicast.policy.apicast"
    },
    {
      "name": "apicast.policy.camel",
      "configuration": {
          "all_proxy": "http://192.168.15.103:8080/",
          "http_proxy": "http://192.168.15.103:8080/",
          "https_proxy": "http://192.168.15.103:8443/"
      }
    }
]

如果未定义 http_proxyhttps_proxy,则使用 all_proxy 值。

使用案例示例

Camel 服务策略旨在使用 Apache Camel 在 3scale 中应用更为精细的策略和转换。此策略支持通过 HTTP 和 HTTPS 与 Apache Camel 集成。如需了解更多详细信息,请参阅 第 6 章 使用 Fuse 中的策略扩展转换 3scale 消息内容

有关使用通用 HTTP 代理策略的详情,请参考 第 4.1.23 节 “代理服务”

项目示例

请参阅 GitHub 上的 Camel 代理策略 中的 camel-netty-proxy 示例。此示例项目显示 HTTP 代理,它将响应正文从 API 后端转换为大写。

4.1.7. 条件策略

条件策略与其他 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

Conditions

确定在 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"
}

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

liquid 支持的变量

  • uri
  • host
  • 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.8. 内容缓存

内容缓存策略允许您根据自定义条件启用和禁用缓存。这些条件只能应用于客户端请求,因为策略中无法使用上游响应。

如果发送了 cache-control 标头,它将优先于 APIcast 设定的超时。

如果 Method 是 GET,则以下示例配置将缓存响应。

配置示例

{
  "name": "apicast.policy.content_caching",
  "version": "builtin",
  "configuration": {
    "rules": [
      {
        "cache": true,
        "header": "X-Cache-Status-POLICY",
        "condition": {
          "combine_op": "and",
          "operations": [
            {
              "left": "{{method}}",
              "left_type": "liquid",
              "op": "==",
              "right": "GET"
            }
          ]
        }
      }
    ]
  }
}

支持的配置

  • 将以下任一方法的内容缓存策略设置为禁用:POSTPUTDELETE.
  • 如果一条规则匹配,并且它启用了缓存,则执行将停止并且不会禁用。这里按优先级排序非常重要。

上游响应标头

NGINX proxy_cache_valid 指令信息只能全局设置,使用 APICAST_CACHE_STATUS_CODESAPICAST_CACHE_MAX_TIME。如果您的上游需要与超时相关的不同行为,请使用 Cache-Control 标头。

4.1.9. 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 请求

数据类型:布尔值

max_age

max_age 属性允许您设置 preflight 请求结果的缓存时长

数据类型:整数

策略对象示例

{
  "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",
   "max_age" : 200
  }
}

有关如何配置策略的详情,请参考 3scale 管理门户中的修改策略链

4.1.10. 自定义指标

自定义 Metrics 策略会添加可用性,以在上游 API 发送的响应后添加指标。此策略的主要用例是根据响应代码状态、标头或不同的 NGINX 变量添加指标。

自定义指标的限制

  • 当在将请求发送到上游 API 之前进行身份验证时,将对后端进行第二次调用,以向上游 API 报告新指标。
  • 此策略不适用于批处理策略。
  • 需要在管理门户中创建指标,然后策略才会推送指标值。

请求流示例

下图显示了未缓存身份验证的请求流示例,以及身份验证缓存时的流。

配置示例

如果上游 API 返回 400 状态,此策略会按标头递增来递增指标错误:

{
  "name": "apicast.policy.custom_metrics",
  "configuration": {
    "rules": [
      {
        "metric": "error",
        "increment": "{{ resp.headers['increment'] }}",
        "condition": {
          "operations": [
            {
              "right": "{{status}}",
              "right_type": "liquid",
              "left": "400",
              "op": "=="
            }
          ],
          "combine_op": "and"
        }
      }
    ]
  }
}

如果上游 API 返回 200 状态,则此策略使用 status_code 信息递增 hits 指标:

{
  "name": "apicast.policy.custom_metrics",
  "configuration": {
    "rules": [
      {
        "metric": "hits_{{status}}",
        "increment": "1",
        "condition": {
          "operations": [
            {
              "right": "{{status}}",
              "right_type": "liquid",
              "left": "200",
              "op": "=="
            }
          ],
          "combine_op": "and"
        }
      }
    ]
  }
}

4.1.11. 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.12. 边缘限制

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

  • 最终用户速率限制:请求授权标头中传递的 JWT 令牌的 sub (subject)声明的速率限制。这配置为 {{ jwt.sub }}
  • 请求每秒(RPS)速率限制.
  • 每个服务的全局速率限值:为每个服务(而不是每个应用)应用限制。
  • 并发连接限制:设置允许的并发连接数。

限制类型

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

  • leaky_bucket_limiters :基于泄漏 bucket 算法,它基于平均请求数加上最大突发大小。
  • fixed_window_limiters :根据固定的时间窗口:最后 n 秒。
  • connection_limiters :基于连接的并发数量。

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

限制定义

这些限制有一个键,对用于定义限制的实体进行编码,如 IP 地址、服务、端点、标识符、特定标头的值和实体。此密钥在限制器的 key 参数中指定。

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

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

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

    • 纯文本(plain
    • Liquid(liquid

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

  • leaky_bucket_limiters: rate, burst.

    • rate:定义可以在不延迟的情况下每秒发出多少个请求。
    • burst:定义每秒的请求量可能超过允许的速率。为超过由 rate 指定的允许费率的请求引入人为延迟。在超过 burst 中定义的每秒请求数后,请求将被拒绝。
  • fixed_window_limiters: count, window. count 定义在 window 中定义的每秒数可以发出的请求数。
  • connection_limitersconnburstdelay.

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

示例

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

    {
      "key": { "name": "service_A" },
      "count": 10,
      "window": 60
    }
  • 允许 100 个连接,突发 10,延迟 1 秒:

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

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

移动模板

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

示例

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

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

应用条件

每个限制器必须具有定义何时应用限制器的条件。条件在限制器的 condition 属性中指定。

condition 由以下属性定义:

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

    • left:操作的左侧部分.
    • left_type :如何评估 left 属性(名文或 liquid)。
    • right:操作的右侧部分.
    • right_type :如何评估 right 的属性(名文或 liquid)。
    • op:Operator 在左侧和右侧部分之间应用。支持以下两个值: == (等于)和 != (不等于)。

示例

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

配置速率限制计数器的存储

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

错误处理

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

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

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

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

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

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

4.1.13. 标头修改

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

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

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

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

  • op:指定要应用的操作。add 操作会为现有标头添加一个值。这个 set 操作会创建一个标头和值,如果已存在该标头的值,则会覆盖现有的标头值。push 操作会创建一个标头和值,但如果已存在,则不会覆盖现有的标头值。相反,push 会将值添加到现有标头中。delete 操作会删除标头。
  • header:指定要创建或修改的标头,可以是可用作标头名称(如 Custom-Header)的任何字符串。
  • value_type :定义如何评估标头值,可以是 plain(用于纯文本),也可以是 liquid(用于 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.14. HTTP 状态代码覆盖

作为 API 供应商,您可以将 HTTP Status Code Overwrite 策略添加到 API 产品中。此策略允许您将上游响应代码改为您指定的响应代码。3scale 将 HTTP Status Code Overwrite 策略应用到从上游服务发送的响应代码。换句话说,当 3scale 公开的 API 返回您情况不匹配的代码时,您可以配置 HTTP 状态代码覆盖策略,以将代码更改为对应用程序有意义的响应代码。

在策略链中,生成您要更改的响应代码的任何策略都必须是 HTTP 状态代码覆盖策略之前。如果没有生成您要更改的 Status Codes 的策略,则 HTTP Status Code Overwrite 策略的策略链位置无关紧要。

在管理门户中,将 HTTP Status Code Overwrite 策略添加到产品的策略链中。在策略链中,单击策略以指定您要更改的上游响应代码以及您要返回的响应代码。单击您要覆盖的每个额外上游响应代码的加号。例如,您可以使用 HTTP 状态代码覆盖策略将上游 201、"Created"、响应代码改为 200,"OK",响应代码。

在超过内容限制时,响应代码可能要更改的另一个示例就是响应。当响应代码为 414 (请求 URI 过长)时,上游可能会返回 413(载荷过大)。

在管理门户中添加 HTTP Status Code Overwrite 策略的替代方法是使用带有策略链配置文件的 3scale API。

示例

策略链配置文件中的以下 JSON 配置将覆盖两个上游响应代码:

{
  "name": "statuscode_overwrite",
  "version": "builtin",
  "configuration": {
    "http_statuses": [
      {
        "upstream": 200,
        "apicast": 201
      },
      {
        "upstream": 413,
        "apicast": 414
      }
    ]
  }
}

4.1.15. IP 检查

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

配置属性

属性描述数据类型必需?

check_type

check_type 属性有两个可能的值: whitelistblacklistblacklist 将拒绝来自列表中 IP 的所有请求。whitelist 将拒绝来自 不在 列表中 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.16. JWT 申索检查

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

关于 JWT 申索检查策略

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

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

Example:如果是 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"
          }
      ]
  }
}

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

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

  • 您需要有权访问 3scale 安装。
  • 您需要等待所有部署完成。

配置策略

  1. 要将 JWT Claim Check 策略添加到您的 API 中,请按照 3scale 管理门户中启用策略中所述的步骤,然后选择 JWT 申索检查。
  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.17. 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.18. 日志

Logging 策略有两个目的:

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

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

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

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

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

所有 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 文件。

示例

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

  • 如果启用了 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.serializable.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"
    }
  }
}

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

对于自定义日志记录,您可以使用 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.19. 维护模式

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

配置属性

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

属性default描述

status

整数,可选

503

响应代码

message

字符串,可选

503 服务不可用 - 维护

响应消息

维护模式策略示例

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

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

4.1.20. NGINX Filter

NGINX 会自动检查某些请求标头并在无法验证这些标头时拒绝请求。例如,NGINX 拒绝具有 NGINX 无法验证的 If-Match 标头的请求。如果您希望 NGINX 跳过特定标头的验证,请添加 NGINX Filter 策略。

添加 NGINX Filter 策略时,您要为需要 NGINX 跳过验证指定一个或多个请求标头。对于您指定的每个标头,您可以指定是否在请求中保留标头。例如,以下 JSON 代码添加了 NGINX 过滤器策略,以便跳过对 If-Match 标头的验证,但在转发到上游服务器的请求中保留 If-Match 标头。

{ "name": "apicast.policy.nginx_filters",
  "configuration": {
    "headers": [
      {"name": "If-Match", "append": true}
    ]
  }
}

下一个示例还跳过了 If-Match 标头的验证,但此代码指示 NGINX 在向上游服务器发送请求前删除 If-Match 标头。

{ "name": "apicast.policy.nginx_filters",
  "configuration": {
    "headers": [
      {"name": "If-Match", "append": false}
    ]
  }
}

无论您是否将指定的标头附加到上游服务器的请求中,当 NGINX 无法验证您指定的标头时,您避免了 NGINX 412 响应代码。

重要

Header Modification 策略 指定相同的标头,对于 NGINX Filter 策略是一个可能的冲突来源。

4.1.21. 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.22. 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 Issuer 设置中的 Token Introspection Endpoint。APIcast 从 token_introspection_endpoint 字段发现 Token Introspection 端点。此字段位于 OIDC 签发者返回的 .well-known/openid-configuration 端点中。

    身份验证类型被设置为 use_3scale_oidc_issuer_endpoint:

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

    • client_id :设置令牌内省端点的客户端 ID。
    • client_secret :设置 Token Inspection Endpoint 的 Client Secret。
    • introspection_url :设置内省端点 URL。

      验证类型设置为 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> header, where <token> is Base64-encoded <client_id>:<client_secret> setting).

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.23. 代理服务

您可以使用 Proxy Service 策略定义一个通用 HTTP 代理,该代理将使用定义的代理发送 3scale 流量。在这种情况下,代理服务充当反向 HTTP 代理,APIcast 将流量发送到 HTTP 代理,代理随后将流量发送到 API 后端。

以下示例显示了流量流:

代理服务策略请求流

发送到 3scale 后端的所有 APIcast 流量都不使用代理。此策略只适用于代理以及 APIcast 和 API 后端之间的通信。

如果要通过代理发送所有流量,则必须使用 HTTP_PROXY 环境变量。

注意
  • Proxy Service 策略禁用所有负载平衡策略,流量发送到代理。
  • 如果定义了 HTTP_PROXYHTTPS_PROXYALL_PROXY 参数,此策略将覆盖这些值。
  • 代理连接不支持身份验证。您可以使用标头修改策略进行身份验证。

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 值。

使用案例示例

代理服务器策略旨在应用更加精细的策略,并在 3scale 中使用 Apache Camel 通过 HTTP 应用更为精细的策略和转换。但是,您还可以将 Proxy Service 策略用作通用 HTTP 代理服务。有关通过 HTTPS 与 Apache Camel 集成的信息,请参阅 第 4.1.6 节 “Camel Service”

项目示例

请参阅 GitHub 上的 camel-netty-proxy 示例。此项目显示 HTTP 代理,它将响应正文从 API 后端转换为大写。

4.1.24. 速率限制标头

当应用程序订阅具有速率限制的应用程序计划时,Rate Limit Headers 策略会添加 RateLimit 标头来响应消息。这些标头提供有关当前时间窗口中配置的请求配额和剩余的请求配额和秒的有用信息。

在产品的策略链中,如果您添加 Rate Limit Headers 策略,则必须在 3scale APIcast 策略之前。如果 3scale APIcast 策略早于 Rate Limit Headers 策略,则 Rate Limit Headers 策略不起作用。

RateLimit 标头

每个消息都添加了以下 RateLimit 标头:

  • RateLimit-Limit:在配置的时间窗口中显示请求总数,例如 10 个请求。
  • RateLimit-Remaining:在当前时间窗口中显示剩余的请求配额,例如 5 个请求。
  • RateLimit-Reset :在当前时间窗口中显示剩余的秒数,例如 30 秒。此标头的行为与 Retry-After 标头的 delta-seconds 表示法兼容。

默认情况下,当没有配置 Rate Limit Headers 策略或应用程序计划没有任何速率限值限制时,响应消息中没有速率限制标头。

注意

如果您请求的 API 指标没有速率限制,但父指标配置了限制,则速率限值标头仍然包含在响应中,因为应用了父限制。

4.1.25. 响应/请求内容限制

作为 API 提供程序,您可以将 Response/Request Content Limits 策略添加到 API 产品。此策略允许您将请求的大小限制为上游 API,以及来自上游 API 的响应大小。如果没有此策略,请求/响应大小将无限制。

此策略有助于防止过载:

  • 后端,因为它必须作用于过大的载荷。
  • 最终用户(API 使用者),因为它收到的数据数量超过其可以处理的数据量。

在请求或响应中,3scale 需要 content-length 标头来应用 Response/Request Content Limits 策略。

在管理门户中,在将 Response/Request Content Limits 策略添加到产品后,单击它以字节为单位指定限值。您可以指定请求限值或响应限值,或同时指定两者。默认值为 0,表示无限大小。

另外,您可以通过更新策略链配置文件来添加此策略,例如:

{
  "name": "apicast.policy.limits",
  "configuration":
  {
    "request": 100,
    "response": 100
  }
}

4.1.26. Retry

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

重要

从 3scale 2.11 开始,无法配置从策略重试的情况。这通过环境变量 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.27. RH-SSO/Keycloak 角色检查

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

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

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

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

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

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

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

    • 纯文本(plain):将 resource 值作为纯文本进行评估。示例: /api/v1/products$.
    • Liquid 文本 (liquid):允许在 resource 值中使用 Liquid。示例: /resource_{{ jwt.aud }} 管理对包含客户端 ID 的资源的访问。
  • methods:根据 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 角色。请参阅红帽单点登录文档中的 Realm 角色

    域角色存在于红帽单点登录发布的 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:定义如何评估名称;值可以是 plain,也可以是 liquid。其工作方式与 resource_type 相同。
  • client_roles :使用 client_roles 检查客户端命名空间中的特定访问角色。请参阅红帽单点登录文档中的客户端角色

    客户端角色存在于 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 值;该值可以是 plain 值,也可以是 liquid 值。其工作方式与 resource_type 相同。
    • client:指定角色的客户端。如果未定义,此策略将 aud 声明用作客户端。
    • client_type :定义如何评估 client 值;值可以是 plain 值或 liquid 值。其工作方式与 resource_type 相同。

4.1.28. 路由

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

重要

当您将路由策略添加到策略链时,路由策略必须始终紧接在标准的 3scale APIcast 策略前。换句话说,路由策略和 3scale APIcast 策略之间没有任何策略。这样可确保 APIcast 发送到上游 API 的请求中正确的 APIcast 输出。以下是正确的策略链的两个示例:

Liquid Context Debug
JWT Claim Check
Routing
3scale APIcast
Liquid Context Debug
Routing
3scale APIcast
JWT Claim Check

路由规则

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

请求路径规则

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

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

标头规则

这是当标头 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"
              }
            ]
          }
        }
      ]
    }
  }

查询参数规则

这是当查询参数 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"
              }
            ]
          }
        }
      ]
    }
  }

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"
              }
            ]
          }
        }
      ]
    }
  }

多操作规则

只有当所有上游都使用 'and' combined_op 评估为 true 时,或者当其中至少一个规则通过使用 'or' combine_op 评估为 true 时,规则可以有多个操作并路由到给定上游。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"
              }
            ]
          }
        }
      ]
    }
  }

组合规则

规则可以组合在一起使用。当有多个规则时,上游选择是首批评估为 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"
              }
            ]
          }
        }
      ]
    }
  }

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": []
          }
        }
      ]
    }
  }

支持的操作

支持的操作有 ==, !=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"
              }
            ]
          }
        }
      ]
    }
  }

移动模板

可以将弹性模板用于配置的值。如果链中的策略将键 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"
              }
            ]
          }
        }
      ]
    }
  }

设置 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.29. 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.30. TLS 客户端证书验证

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

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

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

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

您必须有权访问 3scale 安装。您必须等待所有部署完成。

设置 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

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

要在策略链中配置 TLS 客户端证书验证,您需要 3scale 登录凭据。此外,您需要使用 TLS 客户端证书验证策略配置 APIcast

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

另外:

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

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

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

要验证 TLS 客户端证书验证策略的功能,您需要 3scale 登录凭据。此外,您需要使用 TLS 客户端证书验证策略配置 APIcast

您可以通过在占位符中指定 [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

从白名单中删除证书

要从白名单中删除证书,您需要 3scale 登录凭据。您需要使用 TLS 客户端证书验证策略设置 APIcast。您需要通过在 策略链中配置 TLS 客户端证书验证将证书 添加到白名单。

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

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

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

4.1.31. TLS 终止

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

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

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

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

在策略链中配置 TLS 终止

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

  • 用户签发的证书
  • PEM 格式的服务器证书
  • PEM 格式的证书私钥

按照以下步骤操作:

  1. 要将 TLS 终止策略添加到您的 API 中,请按照 启用标准策略 中所述的步骤操作,然后选择 TLS 终止。
  2. 单击 TLS 终止 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 若要将 TLS 证书添加到策略,可单击加号 + 图标。
  5. 选择证书源:

    • 默认选择 嵌入式证书。上传这些证书:

      • PEM 格式化的证书私钥 :单击 Browse 以选择并上传。
      • PEM 格式的证书 :单击 Browse 以选择并上传。
    • 来自文件系统的证书 - 选择并指定这些证书路径:

      • 证书的路径
      • 证书私钥的路径
  6. 使用 TLS Termination 设置完 API 后,单击 Update Policy

另外:

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

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

验证 TLS 终止策略的功能

您必须有 3scale 登录凭证。您必须已使用 TLS Termination 策略配置了 APIcast

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

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 证书的路径

从 TLS 终止中删除文件

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

删除证书:

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

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

4.1.32. 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.33. 上游连接

Upstream Connection 策略允许您为每个 API 更改以下指令的默认值,具体取决于您在 3scale 安装中配置 API 后端服务器的方式:

  • proxy_connect_timeout
  • proxy_send_timeout
  • proxy_read_timeout

配置上游连接策略:

  • 您必须有权访问 3scale 安装。
  • 您需要等待所有部署完成。

按照以下步骤操作:

  1. 要将 Upstream Connection 策略添加到您的 API 中,请按照 3scale 管理门户中启用策略 中所述的步骤,然后选择 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.34. Upstream Mutual TLS

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

启用 verify 字段后,策略还会验证来自上游 API 的服务器证书。ca_certificates 包含 Privacy Enhanced Mail(PEM)格式的证书,包括 -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- APIcast 使用它来验证服务器。

注意

您必须启用 verify 字段,并填写 ca_certificates 来验证上游 API 的证书。如果没有启用 verify 字段,则只会在上游 API 中检查 APIcast 证书。

要在策略链中配置上游双向 TLS,您需要有权访问 3scale 安装。

  1. 要将 Upstream Mutual TLS 策略添加到您的 API 中,请按照 3scale Admin Portal 中的启用策略 中所述的步骤,然后选择 Upstream Mutual TLS
  2. 单击 Upstream Mutual TLS 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 选择 证书类型

    • path:如果要指定证书的路径,如 OpenShift 生成的证书的路径。
    • embedded:如果要使用第三方生成的证书,请通过从您的文件系统上传证书。
  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# 代表要提升的配置的版本号。

路径配置

使用 OpenShift 和 Kubernetes secret 的证书路径,如下所示:

{
  "name": "apicast.policy.upstream_mtls",
  "configuration": {
      "certificate": "/secrets/client.cer",
      "certificate_type": "path",
      "certificate_key": "/secrets/client.key",
      "certificate_key_type": "path"
  }
}

嵌入式配置

http 表单和文件上传使用以下配置:

{
  "name": "apicast.policy.upstream_mtls",
  "configuration": {
    "certificate_type": "embedded",
    "certificate_key_type": "embedded",
    "certificate": "data:application/pkix-cert;name=client.cer;base64,XXXXXXXXXXX",
    "certificate_key": "data:application/x-iwork-keynote-sffkey;name=client.key;base64,XXXXXXXX"
  }
}

有关其他字段 ca_certificates 并验证 Upstream Mutual TLS、策略配置模式 的详细信息。

其他注意事项

Upstream mutual TLS 策略将覆盖 APICAST_PROXY_HTTPS_CERTIFICATE_KEYAPICAST_PROXY_HTTPS_CERTIFICATE 环境变量值。它使用策略设置的证书,因此这些环境变量不会起作用。

4.1.35. URL Rewriting

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

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

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

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

重写路径的命令

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

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

重写查询字符串的命令

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

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

    • add:为现有参数添加一个值。
    • set:创建 arg(如果没有设置),并在设置时替换其值。
    • push :创建 arg(如果没有设置),并在设置时添加值。
    • delete:删除 arg。
  • arg:操作所应用的查询参数名称。
  • :指定用于查询参数的值。对于值类型"liquid",值应当采用 {{ variable_from_context }} 格式。对于 delete 操作,不考虑该值。
  • value_type :这是可选的。定义如何评估查询参数值,可以是 plain 用于纯文本的值,也可以是 liquid 作为 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.36. 使用 Captures 重写 URL

URL 重写策略是 URL 重写策略的替代选择,允许在将 API 请求传递给 API 后端前重写 API 请求的 URL。

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

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

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

对于每个 API 产品,您可以指定策略链。策略链执行以下操作:

  • 指定 APIcast 适用于请求的策略。
  • 为这些策略提供配置信息。
  • 决定 APIcast 应用策略的顺序。

要在链中正确排序策略,了解 APIcast 如何将策略应用到 API 消费者请求。

4.2.1. APIcast NGINX 阶段如何处理 3scale 策略

3scale API 网关或 APIcast 使用 NGINX 代理 Web 服务器应用策略。当 APIcast 收到来自 API 使用者的请求时,APIcast APIcast 会在一系列 NGINX 阶段处理请求。在每个 NGINX 阶段中,APIcast 可以通过应用这些策略来修改原始请求:

  • 上游 API 策略链中的策略。策略链是策略的顺序列表。默认情况下,上游 API 的策略链包含 3scale APIcast 策略。API 供应商可在 3scale 产品的策略链中添加策略。APIcast 将上游 API 策略链中的策略应用到仅发送到上游 API 的 API 使用者请求。
  • 全球 3scale 策略链中的策略。API 供应商您可以设置 3scale 环境变量来更新全局策略链。APIcast 将全局策略链中的策略应用到所有 API 消费者请求。

如果同一策略位于上游 API 策略链和全局策略链中,则上游 API 策略链中的策略配置具有优先权。

在 APIcast 执行所有 NGINX 阶段所需的处理后,APIcast 会向上游 API 发送请求。因此,为了实现所需的行为,务必要理解 NGINX 阶段处理策略的顺序,因为处理可以修改 API 使用者请求。

NGINX 阶段的顺序和描述

当 APIcast 从 API 使用者接收请求时,APIcast 会通过在上游 API 的策略链和全局策略链中应用策略来处理请求。每个 3scale 策略定义一个或多个功能。APIcast 在一系列 NGINX 阶段执行策略功能。在每个阶段中,NGINX 运行所应用策略中定义的任何功能,并在该阶段指定执行。下表列出了运行策略功能的 NGINX 阶段。额外的 NGINX 阶段(在这个表中没有列出)执行不受策略链中策略顺序的处理。

NGINX 阶段(按顺序排列)本阶段中的处理描述

重写

运行修改请求目标 URI 的任何功能。

权限

运行验证客户端的授权以发出请求的任何功能。

content

生成要发送到上游 API 的请求内容。

NGINX 在 内容 阶段仅应用一个策略。如果策略链中多个策略在请求内容 NGINX 上运行,则仅应用链中最接近的策略。这一点非常重要,因为内置的 3scale APIcast 策略始终在策略链中,需要 NGINX 在 内容 阶段处理。

例如,3scale APIcast 策略和 Upstream 策略都会更新请求来指定上游 API 的路径。NGINX 在 内容 阶段处理这些功能。如果 3scale APIcast 策略在 Upstream 策略之前,则 NGINX 使用上游 API 配置来将其路径添加到修改后的请求。如果 Upstream 策略在 3scale APIcast 策略之前,NGING 会评估 Upstream 策略表达式。当有匹配项时,NGINX 会在修订请求中相应地更改上游 API 路径。

balancer

运行任何负载平衡功能。

header_filter

运行处理请求标头的任何功能。

body_filter

运行处理请求正文的任何功能。

post_action

在 NGINX 同时运行标题和正文功能后运行任何处理请求的功能。

log

生成有关请求的日志信息。

metrics

对从 Prometheus 端点接收的任何数据执行操作。

执行不受策略顺序影响的 NGINX 阶段示例:

  • 当 APIcast 启动时,NGINX 执行与 init 阶段关联的任务。
  • 当 APIcast worker 启动时,NGINX 执行与 init_worker 阶段关联的任务。
  • 当 APIcast 终止 HTTPS 连接时,NGINX 执行与 ssl_certificate 阶段关联的任务。

NGINX 运行策略功能的顺序

API 供应商可以在 3scale 产品中添加一个或多个策略来形成策略链。在每个阶段中,NGINX 处理那些指定在该阶段执行的策略功能。每个策略功能指定 APIcast 在一个 NGINX 阶段中应如何更改其默认行为。例如,在 header_filter 阶段中,GINX 进程指定 header_filter 以及可能对请求标头操作的功能。在每个阶段中,NGINX 按策略链中的顺序处理相关功能。

策略可以通过 上下文 对象共享数据。策略可以读取和修改每个阶段 的上下文 对象。

NGINX 执行策略功能的顺序取决于以下内容:

  • 策略链中策略的位置
  • 处理特定策略功能的 NGINX 阶段

要获得所需行为,您必须正确指定策略链顺序,因为应用策略的结果会根据策略链中的位置而有所不同。下图显示了 NGINX 应用策略的顺序示例。

APIcast NGINX 执行阶段和 3scale 策略链

在上图中,策略 A 首先在策略链中。但是,NGX 首先在策略 B 中处理某个功能,因为该函数与 NGINX 的第一阶段相关,即 重写 阶段。

现在考虑一个包含策略 A、带有以下功能的 policy B 的产品策略链:

  • Policy A 指定:

    • 访问 阶段运行 NGINX 的功能 A1
    • NGINX 在 header_filter 阶段运行的功能 A2
  • Policy B 指定:

    • NGINX 在 重写 阶段运行的功能 B1
    • NGINX 在 header_filter 阶段运行的功能 B2

下图显示了 NGINX 运行该产品的策略功能的顺序。

APIcast NGINX 执行阶段和示例 3scale 策略链

当 APIcast 收到对此产品公开的上游 API 的访问请求时,APIcast 会检查产品的策略链并运行功能,如下表所述:

NGINX 阶段(按顺序排列)NGINX 在此阶段运行的功能

重写

运行 B重写 阶段指定的函数 B1

权限

运行函数 A1 该策略 A访问 阶段指定。

content

策略 A 和 policy B 指定在 内容 阶段执行的功能。

balancer

策略 A 和 policy B 指定在 负载均衡器 阶段执行的功能。

header_filter

策略链指定策略 A,然后指定策略 B。因此,此阶段运行 A 为 header_filter 阶段指定的函数 A 2,然后运行为 header_filter 阶段指定的函数 B 2

body_filter

策略 A 和 policy B 指定在这个阶段执行的功能。

post_action

策略 A 和 policy B 指定在这个阶段执行的功能。

log

策略 A 和 policy B 指定在这个阶段执行的功能。

在本例中,策略 A 最初在策略链中,但策略 B 中的功能是 NGINX 运行的第一个功能。这是因为,策略 B 指定 重写 阶段中 NGINX 进程的功能 B1,这在其它阶段之前。

再举一个例子,请考虑此策略链:

  1. URL Rewriting
  2. 3scale APIcast (分配给所有产品的默认策略)

URL 重写 策略修改请求的目标路径。APIcast 在 重写 阶段运行 URL Rewriting 功能。3scale APIcast 策略定义了 APIcast 在 重写 阶段运行的功能,以及 APIcast 在三个其他阶段运行的功能。当 URL 重写 策略时,3scale APIcast 策略将规则映射到重写的路径。如果 3scale APIcast 策略是第 3scale APIcast 策略,且 URL Rewriting 策略是第二个,则 3scale APIcast 策略将规则映射到原始路径。

4.2.2. 在 3scale 管理门户中修改策略链

修改 3scale 管理门户中的产品策略链,作为 APIcast 网关配置的一部分。

步骤

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

后续步骤

在管理门户的左侧导航面板中,现在有一个警告,表示您没有对 APIcast 进行的配置更改。将策略链更新提升到 Staging APIcast,并根据需要测试更新。确认所需行为后,将更新提升到 Production APIcast。如果 APICAST_CONFIGURATION_CACHE 环境变量设置为一个大于零(默认值)的数字(默认值),则 APIcast 使用更新的配置需要这个秒数。

4.2.3. 在 JSON 配置文件中创建 3scale 策略链

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

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

  • 带有 id 值的 services 对象,指定策略链按编号应用到哪个服务
  • proxy 对象,其中包含 policy_chain 对象和后续对象
  • policy_chain 对象,其中包含定义策略链的值
  • 单独的 policy 对象,用于指定策略和配置策略所需的 nameconfiguration 数据

以下是自定义策略 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 策略会影响策略行为。

4.2.4. 运行 3scale 标准策略功能的 NGINX 阶段

下表列出了标准策略的主要 NGINX 阶段,用于定义 NGINX 在该阶段中运行的功能。表按照 NGINX 进程的顺序列出阶段。

策略链可包含特定阶段中 NGINX 进程的多个策略。在这种情况下,请确保链中策略的顺序是处理 API 请求以获得所需结果的正确顺序。表以字母顺序列出策略。

NGINX 阶段(按顺序排列)定义在这个阶段处理的功能的标准策略

重写

3scale APIcast
3scale Referrer
Anonymous Access
Echo
Header Modification
NGINX Filter
SOAP
Upstream
URL Rewriting
URL Rewriting with Captures
Websocket

权限

3scale APIcast
3scale Batcher
Camel Proxy
Content caching
Edge Limiting
IP Check
JWT Claim Check
RH-SSO/Keycloak Role Check
Maintenance Mode
OAuth 2.0 Mutual TLS 客户端身份验证
OAuth 2.0 Token Introspection
Rate Limit Headers
Response/Request Content Limits
Routing
TLS Client Certificate Validation
Upstream

content

3scale APIcast
Liquid Context Debug
Rate Limit Headers
Routing
Upstream

balancer

Upstream Mutual TLS

header_filter

CORS 请求处理
标头修改
响应/请求内容限制
HTTP 响应代码覆盖写

body_filter

响应/请求内容限制

post_action

3scale APIcast
自定义指标

log

边缘限制
日志记录

4.2.5. 3scale 标准策略和处理它们的 NGINX 阶段

下表列出了标准策略以及运行该策略功能或功能的 NGINX 阶段或阶段。使用此表在策略链中正确排序策略,为上游 API 生成正确的请求。

标准策略运行策略功能的 NGINX 阶段

3scale APIcast

init
重写
内容
post_action
APIcast 将 3scale APIcast 策略应用到所有请求。

Anonymous Access(匿名访问)

重写

3scale Auth 缓存

在策略链中,此策略的位置无关紧要。

3scale Batcher

权限

3scale Referrer

重写

Camel Service

权限

条件策略

在策略链中,此策略的位置无关紧要。

内容缓存

权限

CORS 请求处理

header_filter

自定义指标

post_action

Echo

重写

边缘限制

访问
日志

标头修改

重写
标头_filter

HTTP 响应代码覆盖

header_filter

IP 检查

权限

JWT 申索检查

权限

Liquid Context Debug

content

日志

log

维护模式

权限

NGINX Filter

重写

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

权限

OAuth 2.0 令牌内省

权限

代理服务

在策略链中,此策略的位置无关紧要。

速率限制标头

访问 +内容

响应/请求内容限制

访问
标头_filter
body_filter

Retry

在策略链中,此策略的位置无关紧要。

RH-SSO/Keycloak 角色检查

权限

路由

访问
内容

SOAP

重写

TLS 客户端证书验证

权限

TLS 终止

ssl_certificate

Upstream

重写
访问
内容

上游连接

在策略链中,此策略的位置无关紧要。

Upstream Mutual TLS

balancer

URL Rewriting

重写

使用 Captures 重写 URL

重写

Websocket

重写

4.3. 自定义 3scale APIcast 策略

配置自定义策略以修改 APIcast 行为。首先,定义一个策略链来配置 APIcast 策略,包括您的自定义策略;然后,将策略链添加到 APIcast。

注意

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

APIcast 的自定义策略取决于您的 3scale 部署的配置:

  • 在这些 APIcast 自我管理的部署中添加自定义策略:OpenShift 上的 APIcast 和您安装的容器化环境中的 APIcast。
  • 您无法将自定义策略添加到 APIcast 托管。
警告

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

4.3.1. 关于 3scale APIcast 部署的自定义策略

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

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

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

4.3.2. 在 3scale 嵌入式 APIcast 中添加自定义策略

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

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

警告

构建 apicast-custom-policies 时,构建过程会将新镜像推送到 amp-apicast:latest 标签。当此镜像流上有镜像更改时,apicast-stagingapicast-production 标签都配置为自动启动新部署。为了避免对暂存或生产服务出现任何中断,请取消选择 "Automatically start a new deployment" 复选框来禁用自动部署。或者,为生产环境配置不同的镜像流标签,如 amp-apicast:production

步骤

  1. 使用您在 Creating a registry service account 中创建的凭证创建一个 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. 使用 策略示例分叉公共存储库,或使用其内容创建私有存储库。您需要在 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.11
  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.3.3. 在另一个 OpenShift Container Platform 中将自定义策略添加到 3scale

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

步骤

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

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

    oc new-app -f customizedApicast.yml
注意

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

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

4.3.4. 在 3scale 自定义策略中包含外部 Lua 依赖项

您可以将外部 Lua 依赖项添加到自定义策略中,以便 APIcast 可以使用 3scale 镜像中没有的 Lua 库。

此处的步骤演示了如何使用自定义策略示例来将 响应正文从 JSON 转换为 XML。自定义策略示例需要 xml2lua XML 解析器,该解析器使用 Lua 编写。完整的示例显示了用于构建和测试的简短示例,但您无法仅遵循示例过程来部署自定义策略。要部署具有外部 Lua 依赖项的自定义策略,您必须执行此流程中的步骤,以及 在另一个 OpenShift Container Platform 中将自定义策略添加到 3scale

JSON 到 XML 自定义策略只是示例。它不可用于生产环境。

先决条件

  • 3scale 自定义策略
  • 访问外部 Lua 库

步骤

  1. 在包含自定义策略的目录中,添加一个可识别外部 Lua 库的文件。

    文件的名称必须是 Roverfile。在 JSON 到 XML 自定义 策略示例中,Roverfile 具有此内容:

    luarocks {
    	group 'production' {
    		module { 'xml2lua' },
    	}
    }

    Lua -rover 是一个围绕 LuaRocks. lua-rover 的打包程序,提供依赖项的传递锁定。LuaRocks 是 Lua 模块的软件包管理器。

  2. 在包含自定义策略的目录中,添加 a lua-rover 锁定文件。

    文件的名称必须是 Roverfile.lock。在 JSON 到 XML 自定义 策略示例中,Roverfile.lock 具有此内容:

    xml2lua 1.5-2||productionbash-4.4

    Roverfile 和 Roverfile.lock 一起启用 APIcast 或 3scale 操作器来获取依赖的库。

  3. 在定义自定义策略的 文件中,添加一行来指定 Lua 依赖项。JSON 到 XML 自定义策略示例指定这一行:

    local xml2lua = require("xml2lua")
  4. 在用于构建自定义策略的 Dockerfile 中,复制 RoverfileRoverfile.lock,并运行 rover installJSON 到 XML 自定义策略示例将以下行添加到其 Dockerfile 中:

    COPY Roverfile .
    COPY Roverfile.lock .
    
    RUN rover install --roverfile=/opt/app-root/src/Roverfile

    您的 Dockerfile 可以使用 APIcast 或 3scale operator 来构建策略。

  5. 在自定义 策略的 Makefile 中,指定任何自定义策略的 构建 目标。

    例如,构建 目标可能类似如下:

    TARGET_IMAGE="apicast/json_to_xml:latest"
    # IP="http://localhost:8080"
    
    build:
    	docker build . --build-arg IMAGE=registry.redhat.io/3scale-amp2/apicast-gateway-rhel8:3scale2.11 -t $(TARGET_IMAGE)

后续步骤

部署具有外部 Lua 依赖项的自定义策略的其余步骤与部署其他自定义策略的步骤相同。也就是说,您需要将镜像推送到存储库,并将 APIcast 镜像替换为您刚才构建的镜像。

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

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

THREESCALE_CONFIG_FILE=example.json bin/apicast

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

一些 标准策略 支持 Liquid 模板化,它不仅允许使用纯字符串值,也允许在请求上下文中使用变量。

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

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

  • uri:此路径中排除的查询参数请求的路径。嵌入式 NGINX 变量的值 $uri
  • host:请求的主机,这是嵌入式 NGINX 变量 $host 的值。
  • remote_addr :客户端的 IP 地址,这是嵌入式 NGINX 变量 $remote_addr 的值。
  • headers:包含请求标头的对象。使用 {{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.17 节 “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 消息内容

您可以使用红帽 Fuse 为红帽 3scale API 管理创建高度灵活的策略扩展。您可以通过在 OpenShift 上的 Fuse 中创建策略扩展,然后将它们配置为 3scale 管理门户中的策略。使用 APIcast Camel 代理策略,您可以对请求和响应消息内容执行复杂的转换,例如 XML 到 JSON,它们在 Apache Camel 集成框架中实施。

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

注意

如果您已在 3scale API 后端中使用 Fuse Camel 应用程序,则不需要此功能。在这种情况下,您可以使用现有的 Fuse Camel 应用程序来执行转换。

所需的软件组件

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

  • OpenShift 7.10 上的 Fuse
  • 3scale 内部部署 2.11
  • APIcast 嵌入式(默认暂存和生产)或 APIcast 自管理

您可以在 3scale 之外的其他 OpenShift 项目中部署自定义 Fuse 策略,但这不是必需的。但是,您必须确保两个项目间的通信成为可能。详情请参阅使用 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 正文转换为大写。
  • 目标服务的响应是通过将其转换为大写,然后返回到客户端来处理的。
  • 本例显示了 HTTP 和 HTTPS 用例所需的配置。

先决条件

  • 您必须在 OpenShift 7.10 上部署 Fuse,并且 3scale 2.11 部署到同一 OpenShift 集群中。有关安装详情,请参阅:

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

步骤

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

    以下简单示例从服务执行请求和响应的大写转换:

    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.Locale;
    
    import org.apache.camel.Exchange;
    import org.apache.camel.Message;
    import org.apache.camel.builder.RouteBuilder;
    import org.apache.camel.model.RouteDefinition;
    
    public class ProxyRoute extends RouteBuilder {
    
        @Override
        public void configure() throws Exception {
            final RouteDefinition from;
            if (Files.exists(keystorePath())) {
                from = from("netty4-http:proxy://0.0.0.0:8443?ssl=true&keyStoreFile=/tls/keystore.jks&passphrase=changeit&trustStoreFile=/tls/keystore.jks"); 1
            } else {
                from = from("netty4-http:proxy://0.0.0.0:8080");
            }
    
            from
                .process(ProxyRoute::uppercase)
                .toD("netty4-http:"
                    + "${headers." + Exchange.HTTP_SCHEME + "}://" 2
                    + "${headers." + Exchange.HTTP_HOST + "}:"
                    + "${headers." + Exchange.HTTP_PORT + "}"
                    + "${headers." + Exchange.HTTP_PATH + "}")
                .process(ProxyRoute::uppercase);
        }
    
        Path keystorePath() {
            return Path.of("/tls", "keystore.jks");
        }
    
        public static void uppercase(final Exchange exchange) { 3
            final Message message = exchange.getIn();
            final String body = message.getBody(String.class);
            message.setBody(body.toUpperCase(Locale.US));
        }
    
    }
    1
    在这个简单示例中,如果您的 Java 密钥存储文件挂载于 /tls/keystore.jks,侦听端口将设置为 8443
    2
    3scale 调用 Camel 代理策略时,会根据 3scale 中为后端 API 配置的值自动设置 HTTP_SCHEMEHTTP_HOSTHTTP_PORTHTTP_PATH 标头的值。
    3
    这个简单示例将消息内容转换为大写。您可以使用 Camel Enterprise Integration Patterns 对请求和响应消息内容(例如 XML 到 JSON)执行更复杂的转换。
  2. 在 OpenShift 上部署您的 Camel 应用程序并将其公开为服务。如需了解更多详细信息,请参阅在 OpenShift 的 Fuse 上创建和部署应用程序

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

在 OpenShift 上使用 Fuse 实施 Apache Camel 转换后,您可以使用 3scale 管理门户将其配置为 APIcast 策略链中的策略扩展。

策略扩展允许您配置 3scale 产品以使用 Camel HTTP 代理。此服务用于通过 HTTP 代理发送 3scale 流量,以在第三方代理中执行请求响应修改。在这种情况下,第三方代理是使用 OpenShift 中的 Fuse 实施 Apache Camel。您还可以配置 APIcast,以使用 TLS 安全地连接到 Camel HTTP 代理服务。

注意

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

先决条件

步骤

  1. 在 3scale Admin Portal 中,选择 Integration > Policies
  2. 选择 POLICIES > Add policy > Camel Service
  3. 在相应字段中输入用于连接到 Camel HTTP 代理服务的 OpenShift 路由:

    • https_proxy:使用 http 协议和 TLS 端口连接到 Camel HTTP 代理,例如:

      http://camel-proxy.my-3scale-management-project.svc:8443
    • http_proxy:使用 http 协议和端口连接到 Camel HTTP 代理,例如:

      http://camel-proxy.my-3scale-management-project.svc:8080
    • all_proxy :在协议未指定的情况下,使用 http 协议和端口连接到 Camel HTTP 代理,例如:

      http://camel-proxy.my-3scale-management-project.svc:8080
  4. 将更新的策略配置提升到您的暂存或生产环境。例如,点 Promote v.3 to Staging APIcast.
  5. 使用 3scale curl 命令测试 APIcast 策略配置,例如:

    curl "https://testapi-3scale-apicast-staging.myuser.app.dev.3sca.net:443/?user_key=MY_USER_KEY" -k

    APIcast 建立一个新的 TLS 会话,用于连接 Camel HTTP 代理。

  6. 确认消息内容已转换,本例中将转换为大写。
  7. 如果要绕过 APIcast 并直接使用 TLS 测试 Camel HTTP 代理,则必须使用自定义 HTTP 客户端。例如,您可以使用 netcat 命令:

    $ print "GET https://mybackend.example.com HTTP/1.1\nHost: mybackend.example.com\nAccept: */*\n\n" | ncat --no-shutdown --ssl my-camel-proxy 8443

    本例使用 GET 后的完整 URL 创建 HTTP 代理请求,并使用 ncat --ssl 参数在端口 8443 上指定 与 my-camel-proxy 主机的 TLS 连接。

    注意

    您不能使用 curl 或其他通用 HTTP 客户端直接测试 Camel HTTP 代理,因为代理不支持使用 CONNECT 方法进行 HTTP 隧道。通过 CONNECT 使用 HTTP 隧道时,传输是端到端加密,不允许 Camel HTTP 代理调节载荷。

第 7 章 APIcast 环境变量

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

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

all_proxy,ALL_PROXY

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

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

APICAST_ACCESS_LOG_BUFFER

Default: 没有值

value: 正整数

允许以字节的块的形式包含访问日志写入。结果为更少的系统调用,这可以提高网关的性能。

APICAST_ACCESS_LOG_FILE

Default: stdout

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

APICAST_BACKEND_CACHE_HANDLER

Values: strict | resilient

Default: strict

Deprecated:改为使用 Caching 策略。

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

APICAST_CACHE_MAX_TIME

默认:1m

Value: 字符串

在系统中选择要缓存的响应时,此变量的值表示要缓存的最长时间。如果未设置 cache-control 标头,则缓存的时间将是定义的标头。

此值的格式由 proxy_cache_valid NGINX 指令定义。

此参数仅供使用内容缓存策略的 API 使用,并且请求符合缓存条件。

APICAST_CACHE_STATUS_CODES

默认:200, 302

Value: 字符串

当上游的响应代码与此环境变量中定义的一个状态代码匹配时,响应内容将缓存在 NGINX 中。缓存时间取决于其中一个值:标头缓存时间值或 APICAST_CACHE_MAX_TIME 环境变量定义的最长时间。

此参数仅供使用内容缓存策略的 API 使用,并且请求符合缓存条件。

APICAST_CONFIGURATION_CACHE

:数字

Default: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

Deprecated:改为使用 策略

定义实施自定义逻辑的 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

Default: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

Deprecated:改为使用 策略

指定实施 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

Default: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

Default:0

:整数 >= 0

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

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

APICAST_RESPONSE_CODES

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

默认 :<empty>(false)

当设置为 true 时,APIcast 将记录 3scale 中 API 后端返回的响应代码。如需更多信息,请参阅 为您的 API 设置和评估 3scale 响应代码日志

APICAST_SERVICE_CACHE_SIZE

:整数 >= 0

Default:1000

指定 APIcast 可存储在内部缓存中的服务数量。高值会影响性能,因为 Lua 的 lru 缓存将初始化所有条目。

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. 应用到后端端点的 Regexp 过滤器

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

在这种情况下,13 在 APIcast 中配置,24 将被丢弃。

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

Default: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

默认值: no value 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 优先

要使用网关配置来构建文件,根据服务数量,有两个替代方案:

  • 选项 1.使用 URL 从管理门户下载配置:

    <schema>://<admin-portal-domain>/admin/api/nginx/spec.json

    请考虑以下几点:

    • 在超过 20 个服务后,端点会受到限制。
    • 您可以在 https://account-admin.3scale.net/admin/api/nginx/spec.json中看到示例:
  • 选项 2.使用可用的 3scale API 端点:

    • Proxy Config ShowProxy Config Show Latest.
    • 然后,迭代服务以构建配置文件。在这一步中,使用可用的 3scale API 端点或等同的 3scale toolbox 命令

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

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

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

THREESCALE_DEPLOYMENT_ENV

: stage | production

默认 :production

此环境变量的值定义从中下载配置的环境;这是使用新 APIcast 时的 3scale 暂存或生产。

在对 3 scale 服务管理 API 的授权/报告请求中,该值也将用于标题 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 后端服务器发出的请求数量来缩短延迟并提高吞吐量。为实现这一目标,此策略会缓存授权状态和批处理报告。

详情请参阅 3scale Batcher 策略。下图说明了策略的工作原理。

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 - 同时拥有 3scale 托管或内部部署的 API 管理器。
  • 在 3scale On-premises 中嵌入 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

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

注意

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

其他资源

有关 Prometheus 的详情请参考 Prometheus:Getting Started.

9.3. 3scale APIcast 的 OpenShift 环境变量

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

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

环境变量DescriptionDefault(默认)

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 默认指标” 中列出的指标。

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

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

指标Description类型标签

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

指标Description类型标签

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. 先决条件

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 key 字符串。
  • 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 安全性的环境中使用这些模式。以下是可以在令牌和应用程序上执行的操作:

  • 应用程序 Suend:这会挂起应用对 API 的访问,实际上,所有带有相关键的 API 调用将被暂停。
  • 应用程序 Resume:撤销应用暂停操作的影响。
  • 主要重新生成:此操作为应用生成一个新的随机字符串密钥,并将它与应用相关联。立即执行此操作后,对前一个令牌的调用将不再被接受。

后一操作可以从管理门户中的 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 值。使用 Referrer 标头的目的信息包括在 RFC 7231, section 5.5.2:Referer.

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

要启用 Adrer Filtering 功能,请转至 [your_API_name] > Applications > Settings > Usage Rules。选择 Require referr filter 并点击 Update Product

启用推荐程序过滤器

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

在 Developer Portal 中配置推荐

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

在 Developer Portal 中配置推荐

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

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

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 字段来配置集成。具体步骤请查看 3scale 与红帽单点登录集成

12.1. APIcast 验证和解析 JWT

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

Authorization: Bearer <JWK>

Example:

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 会执行以下操作:

  1. 使用公钥验证 JWT 令牌。
  2. 验证声明 nbfexp
  3. 验证声明中指定的签发者 iss(Issuer)是否与 OpenID Connect Issuer 字段中配置的相同。
  4. 提取 azpaud 声明的值,并将其用作客户端 ID,以标识 3scale 中的应用程序,以通过 Service Management API 授权调用。

如果有任何 JWT 验证或授权检查失败,APIcast 会返回 Authenication 失败 错误。否则,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 实例传达更改。

3scale 与红帽单点登录部分集成 提供了确保 zync-que 具有使用 RH-SSO API 的正确凭据所需的步骤。

12.3. 3scale 与红帽单点登录集成

作为 API 提供程序,将 3scale 与红帽单点登录(RH-SSO)集成为身份提供程序(IdP)是对 API 请求进行身份验证的选项。集成由配置以下元素组成:

12.3.1. 将 Zync 配置为使用自定义 CA 证书

您必须在 Zync 和红帽单点登录(RH-SSO)之间建立 SSL 连接,因为 Zync 使用 RH-SSO 运行来交换令牌。如果您没有在 Zync 和 RH-SSO 之间配置 SSL 连接,则会为侦听的任何人打开令牌。

3scale 2.2 及更高版本支持 RH-SSO 的自定义 CA 证书和 SSL_CERT_FILE 环境变量。此变量指向证书捆绑包的本地路径。

先决条件

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

    curl https://rhsso-fqdn
注意
  • 些版本的 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
  2. 使用以下 cURL 命令验证新证书:预期响应是 域的 JSON 配置。如果验证失败,这表示您的证书可能不正确。

    curl -v https://<secure-sso-host>/auth/realms/master --cacert customCA.pem
  3. 将证书捆绑包添加到 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"}]}}'
  4. 部署后,验证证书是否已附加,内容是否正确:

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

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

12.3.2. 配置红帽单点登录

创建并配置 Zync 以使用自定义 CA 证书后,您必须在 Red Hat Single Sign-On(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。

先决条件

步骤

  1. 启用 OpenID Connect:

    1. 选择您要启用 OpenID Connect 身份验证的服务,导航到 [your_product_name] > Integration > Settings
    2. Authentication 选项中,选择 OpenID Connect Use OpenID Connect for any OAuth 2.0 flow.
  2. 编辑 APIcast 配置。为 OpenID Connect 选择选项后,您会看到 OpenID Connect(OIDC)Basics 的新部分:

    1. 选择 OpenID Connect Issuer Type
    2. 指定 OpenID Connect Issuer 字段,使用位于主机 <rhsso_host> 和端口 <rhsso_port> 的 RH-SSO 服务器的 URL 输入之前记录的客户端凭证,如以下 URL 模板所示:

        https://<client_id>:<client_secret>@<rhsso_host>:<rhsso_port>/auth/realms/<realm_name>
    3. 要保存配置,请点击 Update Product

12.4. 配置与第三方身份提供程序的 HTTP 集成

您可以配置 OpenID Connect(OIDC)的 HTTP 集成,以便于与第三方身份提供程序(IdP)同步凭证。这意味着,可以通过实施我们提供的 OpenAPI 规格来集成红帽单点登录(RH-SSO)以外的不同 IdP。

12.4.1. 先决条件

12.4.2. 步骤

要配置 OIDC 与第三方身份提供程序的 HTTP 集成,请在管理门户中按照以下步骤执行:

  1. 导航到 [Your_product_name] > Integration > Settings
  2. AUTHENTICATION 下,选择 OpenID Connect Use OpenID Connect for any OAuth 2.0 flow.
  3. AUTHENTICATION SETTINGS 下指定 OpenID Connect (OIDC) Basics

    1. OpenID Connect Issuer Type 中,指定 OpenID 提供程序的类型。
    2. OpenID Connect Issuer 中,指示 OpenID 提供程序的位置。
  4. 要保存您的更改,请点击 Update Product

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:/API 作为 OpenID Connect Issuer

12.4.3.2. 创建、更新和删除客户端

Zync 发出以下创建、更新或删除客户端请求:

  • 创建和更新 → PUT /clients/:client_id
  • 删除 → DELETE /clients/:client_id

所有端点必须以 2xx 状态代码进行回复。否则,将重试请求。

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"
}

使用 OAuth2 协议 时,Zync 使用 token_endpoint 来交换 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 中,如果您创建一个启用了 OIDC 身份验证的客户端,则 RH-SSO 中创建的 Zync 创建的对应客户端仅启用授权代码流。建议将此流程作为最适合大多数情况的最安全和最合适的流程。不过,也可以启用其他流。

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_product_name] > Integration > Settings
  2. AUTHENTICATION 下,选择 OpenID Connect Use OpenID Connect for any OAuth 2.0 flow。启用对应的流:

    • standardFlowEnabled (身份验证代码流)[默认选择]
    • hiddenFlowEnabled (Implicit 流)
    • ServiceAccountsEnabled (服务帐户流)
    • directAccessGrantsEnabled (直接访问授予流)
  3. 选择一个或多个流。
  4. 要保存您的更改,请点击 Update Product

12.6. 测试集成

要测试集成,您必须执行以下部分中列出的步骤。

12.6.1. 测试客户端同步

要测试客户端同步,请执行以下步骤:

  1. 为配置了 OpenID Connect 集成的服务创建一个应用。
  2. 注意生成的应用的客户端 ID 和客户端 Secret。
  3. 验证配置的 Red Hat Single Sign-On 域中现在存在具有相同客户端 ID 和客户端机密的客户端。
  4. 在 3scale 管理门户中更新应用的重定向 URL。重定向 URL 应尽量具体。
  5. 验证红帽单点登录中的客户端 Valid Redirect URIs 字段是否已相应地更新。

12.6.2. 测试 API 授权流

要测试 API 授权流,请执行以下步骤:

  1. 使用对应的 RH-SSO 客户端上启用的 OAuth 2.0 流从红帽单点登录服务器获取访问令牌。
  2. Authorization 标头中使用从 RH-SSO 检索的 access_token 的值,如下所示:Authorization:Bearer <access_token>

如果令牌正确且 3scale 中的对应应用获得授权,APIcast 网关会从 API 后端返回响应。

12.7. 集成示例

3scale 中的服务"API"配置为使用 OpenID Connect 身份验证。服务 "API" 上的 公共基础 URL 配置为 https://api.example.comPrivan Base URL 配置为 https://internal-api.example.com

OpenID Connect Issuer 字段在 API 集成中被设置为 https://zync:41dbb98b-e4e9-4a89-84a3-91d1d19c4207@idp.example.com/auth/realms/myrealm,而 realm myrealm 中的 client zync 具有正确的服务帐户角色。

在 3scale 中,有一个应用具有 myclientid 客户端 ID、myclientsecret 客户端机密和 https://myapp.example.com 重定向 URL。在 Red Hat Single Sign-On 中,在 myrealm realm 中,还有一个带有 myclientid 客户端 ID、myclientsecret secret 和 https://myapp.example.com Valid Redirect URI 的客户端。在此客户端上启用标准流。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 显示登录窗口,用户必须在其中提供用户的凭证:用户名 myuser 和密码 mypassword
  3. 根据配置,如果这是用户首次在此特定应用中进行身份验证,则将显示同意窗口。
  4. 用户通过身份验证后,applciation 使用端点 https://idp.example.com/auth/realms/myrealm/protocol/openid-connect/token 发送 Token 请求到 RH-SSO,并提供客户端 ID myclientid、客户端 secret myclientsecret 和 Redirect URL https://myapp.example.com
  5. RH-SSO 返回一个 JSON,带有一个 "access_token" 项 eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArNhqF-A.
  6. 应用程序使用标头 Authorization 将 API 请求发送到 https://api.example.com :Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArNhqF-A.
  7. 该应用应该会收到来自 https://internal-api.example.com 的成功响应。