Menu Close
Settings Close

Language and Page Formatting Options

管理 API 网关

Red Hat 3scale API Management 2.9

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

摘要

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

前言

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

部分 I. API 网关

第 1 章 操作 APIcast

本节论述了在使用高级 APIcast 配置时需要考虑的概念。

1.1. 公共基础 URL

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

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

注意

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

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

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

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

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

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

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

如果您有多个 API 产品,请为每个产品设置适当的公共基础 URL。APIcast 将基于主机名路由请求。

1.2. 映射规则

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

Mapping Rules

这个规则意味着,以 / 开头的任何 GET 请求都会将指标 hits 递增 1。此规则将匹配对您的 API 的任何请求。但是,您很有可能会更改此规则,因为它太通用,而且通常会在添加更为具体的规则时导致双计数。

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

Hello World Mapping Rules

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

映射规则在 API 产品和 API 后端级别上工作。在本节中,您将了解在各个级别上映射规则的行为,以及描述映射规则如何操作的示例。

在产品级别映射规则

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

在后端级别映射规则

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

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

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

/hello
/bye
  • Cool API 产品:

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

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

1.2.2. 映射规则的匹配

映射规则的匹配通过前缀来执行,可能任意复杂。表示法遵循 OpenAPI 和 ActiveDocs 规格:

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

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

1.2.3. 映射规则工作流

映射规则有以下工作流:

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

添加映射规则

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

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

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

停止其他映射规则

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

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

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

1.3. 主机标头

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

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

Host Rewrite

1.4. 保护 API 后端

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

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

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

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

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

1.6. 使用 OpenTracing 配置 APIcast

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

1.6.1. 先决条件

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

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

1.6.2. 流程

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

  • OPENTRACING_TRACER:定义要使用的追踪器实施。目前,只有 Jaeger 可用。
  • OPENTRACING_CONFIG:指定 tracer 的默认配置文件。您可以 在这里 看到一个示例。
  • OPENTRACING_HEADER_FORWARD:可选.您可以根据 OpenTracing 配置设置此环境变量。

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

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

1.6.3. 其他信息

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

1.6.4. 在 OpenShift 实例上安装 Jaeger

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

警告

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

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

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

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

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

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

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

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

第 2 章 操作 Docker 容器化环境

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

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

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

docker:无法连接到 Docker 守护进程。此主机上运行的 docker 守护进程是否? 错误消息可能是 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 中设置此标头的值。

Proxy secret token

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

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

3.2. 凭证

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

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

Custom user_key

另外,对于 app_idapp_key

Custom app_key/app_id

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

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

Proxy Credentials Location
注意

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

3.3. 配置错误消息

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

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

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

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

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

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

  1. [Your_product_name] > Integration > Settings 中导航
  2. 网关响应 下,选择您要配置的错误类型。
  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 APIcast 或 Production 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 请求每一次递增了方法(指标) version_1word

3.6. 路径路由

APIcast 处理 3scale 帐户中配置的所有 API 服务(如果配置了 APICAST_SERVICES_LIST 环境变量,则为服务子集)。通常,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 公共基本 URL: api.example.com 映射规则: /c

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

如果 启用了 路径路由(APICAST_PATH_ROUTING=true),则调用将同时与主机和路径匹配。因此:

  • api.example.com/a 将路由到服务 A
  • api.example.com/c 将路由到服务 C
  • api.example.com/b 将失败并显示"不匹配规则匹配的"错误,即它不匹配服务 B,因为 公共基础 URL 不匹配。

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

第 4 章 APIcast 策略

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

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

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

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

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

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

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

4.1. APIcast 标准策略

3scale 提供以下标准策略:

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

4.1.1. 3scale 身份验证缓存

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

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

1.严格 - 仅缓存授权的调用.

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

2.弹性 - 根据后端停机时的最后一个请求授权。

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

3.Allow - 当后端停机时,允许所有内容,除非之前看到并且被拒绝。

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

重要

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

4.none - 禁用缓存。

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

配置属性

属性description必需?

caching_type

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

数据类型:枚举的字符串 [弹性、严格、允许、无]

策略对象示例

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

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

4.1.2. 3scale Batcher

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

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

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

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

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

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

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

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

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

    • 当缓存当前调用的授权时,APIcast 将使用缓存的值。在 auths_ttl 参数中设置的时间后,APIcast 会移除缓存,并调用 3scale 后端来检索授权状态。
    • auths_ttl 参数设置为 0 以外的值。将 auths_ttl 设置为 0 的值会在请求第一次缓存时更新授权计数器,从而导致速率限制无效。
  • batch_report_seconds: 设置批处理报告 APIcast 发送到 3scale 后端的频率。默认值为 10 秒。
重要

要使用这个策略,在策略链中启用 3scale APIcast3scale Batcher 策略。

4.1.3. 3scale Referencerer

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

有关推荐程序 过滤 如何工作的更多信息,请参阅 身份验证模式下的推荐程序过滤器部分

4.1.4. 匿名访问

匿名访问策略会公开一项服务,无需身份验证。例如,这对无法适应发送身份验证参数的传统应用程序很有用。匿名策略仅支持使用 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 调用未提供任何凭据,则用于授权的应用 ID。
  • app_key仅适用于 app_id_and_app_key 身份验证类型):如果 API 调用未提供凭据,则用于授权的应用密钥。
  • user_key (仅适用于 user_key auth_type):如果 API 调用未提供凭据,则会用于授权应用的 API 密钥。

图 4.1. 匿名访问策略

Anonymous Access policy

4.1.5. APIcast 缓存

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

如果发送了 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"
            }
          ]
        }
      }
    ]
  }
}

4.1.5.1. 支持的配置

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

4.1.5.2. 上游响应标头

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

4.1.6. Camel 服务

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

以下示例显示了流量流:

Camel Service policy request flow

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

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

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

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

4.1.6.1.1. 使用案例示例

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

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

项目示例

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

4.1.7. 条件策略

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

重要

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

以下示例假定 Conditional Policy 定义以下条件: the request method is POST

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

                             |
                             v

                          Headers

                             |
                             v

                       URL Rewriting

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

  1. APIcast
  2. 缓存
  3. 标头
  4. URL 重写
  5. 上游

当请求不是 POST 时,每个阶段的执行顺序如下:

  1. APIcast
  2. 缓存
  3. 上游

4.1.7.1. 条件

确定是否可以使用 JSON 表达条件策略链中的策略并使用临时模板的条件。

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

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

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

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

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

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

4.1.7.1.1. 颠覆性支持的变量
  • uri
  • 主机
  • remote_addr
  • headers['Some-Header']

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

这个示例在请求的 Backend 标头处于 暂存 时执行上游策略:

{
   "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. CORS 请求处理

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

  • 允许的标头
  • 允许的方法
  • 允许的凭证
  • 允许的原始标头

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

注意

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

配置属性

属性description必需?

allow_headers

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

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

allow_methods

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

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

allow_origin

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

数据类型:字符串

allow_credentials

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

数据类型:布尔值

策略对象示例

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

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

4.1.9. 自定义指标

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

4.1.9.1. 自定义指标的限制

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

4.1.9.2. 请求流示例

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

4.1.9.3. 配置示例

如果上游 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.10. echo

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

配置属性

属性description必需?

status

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

数据类型:整数

Exit

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

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

策略对象示例

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

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

4.1.11. 边缘限制

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

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

4.1.11.1. 限制类型

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

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

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

4.1.11.2. 限制定义

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

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

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

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

    • 纯文本(plain)
    • as Liquid(liquid)

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

  • leaky_bucket_limiters: rate, burst.

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

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

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

4.1.11.3. 移动模板

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

示例

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

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

4.1.11.4. 应用条件

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

condition 使用以下属性定义:

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

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

示例

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

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

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

4.1.11.6. 错误处理

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

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

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

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

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

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

4.1.12. 标头修改

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

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

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

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

  • op: 指定要应用的操作。add 操作为现有标头添加一个值。set 操作会创建一个标头和值,并在已存在标头值时覆盖现有的标头值。push 操作会创建一个标头和值,但如果已存在,则不会覆盖现有的标头值。相反,push 会将值添加到现有标头中。delete 操作删除标头。
  • header: 指定要创建或修改的标头,可以是可用作标头名称的任何字符串(例如 Custom-Header)。
  • value_type: 定义如何评估标头值,可以是 plain (纯文本)或 liquid (评估为 Liquid 模板)。如需更多信息,请参阅 第 5.1 节 “在策略中使用变量和过滤器”
  • value: 指定将用于标头的值。对于值类型 "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.13. IP 检查

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

配置属性

属性description数据类型必需?

check_type

check_type 属性有两个可能的值,即 whitelistblacklistblacklist 将拒绝来自列表上 IP 的所有请求。whitelist 将拒绝来自列表 以外的 IP 的所有请求。

字符串,必须是 whitelist 或者 blacklist

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-ForX-Real-IPlast_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.14. JWT Claim Check

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

4.1.14.1. 关于 JWT 申索检查策略

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

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

示例:如果 GET 请求,JWT 需要将角色声明设为 admin,否则请求将被拒绝。另一方面,任何非 GET 请求都不会验证 JWT 操作,因此允许 POST 资源而无需 JWT 约束。

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

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

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

先决条件:

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

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

4.1.15. 移动上下文调试

注意

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.16. 日志记录

Logging 策略有两个目的:

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

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

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

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

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

4.1.16.1. 所有 API 的全局配置

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

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

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

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

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

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

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

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

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

4.1.16.2. 示例

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

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

禁用访问日志

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

启用自定义访问日志

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

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

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

使用 JSON 格式配置访问日志

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

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

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

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

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

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

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

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

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

    • THREESCALE_CONFIG_FILE
    • THREESCALE_PORTAL_ENDPOINT

4.1.17. 维护模式

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

配置属性

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

属性valuedefaultdescription

status

整数,可选

503

响应代码

message

字符串,可选

503 服务不可用 - 维护

响应消息

维护模式策略示例

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

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

4.1.18. 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.19. 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,以及服务集成页面上配置的 OIDC Issuer 设置中的 Token Introspection Endpoint。APIcast 从 token_introspection_endpoint 字段中发现 Token Introspection 端点。此字段位于 OIDC 签发者返回的 .well-known/openid-configuration 端点中。

例 4.1. 验证类型设置为 use_3scale_oidc_issuer_endpoint

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

    • client_id:设置令牌内省端点的客户端 ID。
    • client_secret:设置令牌内省端点的客户端机密。
    • introspection_url:设置内省端点 URL。

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

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

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

OAuth 2.0 Token Introspection Configuration

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

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

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

4.1.20. 代理服务

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

以下示例显示了流量流:

Proxy Service policy request flow

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

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

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

4.1.20.1. Configuration

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

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

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

4.1.20.1.1. 使用案例示例

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

项目示例

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

4.1.21. 速率限制标头

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

4.1.21.1. RateLimit 标头

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

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

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

注意

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

4.1.22. Retry

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

重要

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

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

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

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

无法同时配置检查 - 同一策略中的 黑名单 和白名单,但您可以在 APIcast 策略链中添加多个 RH-SSO/Keycloak 角色检查 策略实例。

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

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

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

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

    • 要访问 /resource1role1 realm 角色。对于没有此 realm 角色的方法,您需要指定 黑名单
    • 名为 role1client1 角色来访问 /resource1
    • 用于访问 /resource1role1role2 域角色。指定 realm_roles 中的角色。您还可以指定各个角色的范围。
    • 应用客户端的客户端角色 role1,它是访问令牌的接收者,可访问 /resource1。使用 liquid 客户端类型为客户端指定 JSON Web Token(JWT)信息。
    • 客户端角色,包括应用客户端的客户端 ID(访问令牌的接收者)来访问 /resource1。使用 liquid 客户端类型为客户端角色的 name 指定 JWT 信息。
    • 名为 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 :定义如何评估名称;名称可以是只读 或易用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 :定义如何评估 名称 值;它可以是 或易用的 方式与 resource_type相同)。
  • client :指定角色的客户端。如果未定义,此策略 将 aud 声明用作客户端。
  • client_type :定义如何评估 客户端 值;它可以是 纯的具有破坏性的( 方式与 resource_type相同)。

4.1.24. 路由

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

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

4.1.24.1. 路由规则

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

4.1.24.2. 请求路径规则

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

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

4.1.24.3. 标头规则

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

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

4.1.24.4. 查询参数规则

这是在查询参数 test_query_arg 的值为 123 时路由到 http://example.com 的配置:

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

4.1.24.5. JWT 声明规则

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

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

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

4.1.24.6. 多操作规则

只有在所有上游都评估为 true 时(使用 'and' combine_op),或者至少有一个规则被评估为 true(使用 'or' combine_op),规则才可以有多个操作并路由到给定上游。combine_op 的默认值为 'and'。

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

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

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

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

4.1.24.7. 组合规则

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

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

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

4.1.24.8. catch-all 规则

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

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

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

4.1.24.9. 支持的操作

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

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

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

4.1.24.10. 移动模板

可以将弹性模板用于配置的值。这允许您在链中的策略将键 my_var 存储到上下文中时使用动态值定义规则。

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

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

4.1.24.11. 设置中使用的主机 host_header

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

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

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

4.1.25. SOAP

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

配置属性

属性description必需?

pattern

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

数据类型:字符串

metric_system_name

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

data type: string,必须是有效的 指标

策略对象示例

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

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

4.1.26. TLS 客户端证书验证

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

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

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

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

先决条件:

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

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

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

    注意

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

  2. 只用于测试目的,您可以使用没有缓存和临时环境以及 --param 标记的 lazy 加载程序来进行测试

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

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

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

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

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

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

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

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

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

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

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

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

先决条件

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

另外:

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

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

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

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

先决条件:

4.1.26.3.1. 验证策略功能

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

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

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

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

4.1.26.4. 从白名单中删除证书

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

先决条件

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

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

4.1.26.5. 参考材料

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

4.1.27. TLS 终止

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

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

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

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

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

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

先决条件

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

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

另外:

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

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

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

先决条件

4.1.27.2.1. 验证策略功能

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

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

其中:

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

4.1.27.3. 从 TLS 终止中删除文件

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

先决条件

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

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

4.1.28. 上游

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

例如:

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

策略链参考:

属性description必需?

regex

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

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

url

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

data type: string, ensure this is valid URL

策略对象示例

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

      }
    ]
  }
}

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

4.1.29. 上游连接

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

  • proxy_connect_timeout
  • proxy_send_timeout
  • proxy_read_timeout

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

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

先决条件

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

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

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

4.1.30. 上游双向 TLS

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

4.1.30.1. 在策略链中配置上游双向 TLS

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

先决条件

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

流程

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

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

推进您的更改:

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

    • v# 表示要提升的配置的版本号。

4.1.31. URL 重写

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

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

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

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

4.1.31.1. 重写路径的命令

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

  • op: 要应用的操作.可用的选项有: subgsubsub 操作只替换第一个与您指定的正则表达式匹配项。gsub 操作将出现的所有匹配项替换为您指定的正则表达式。请参阅有关子和 g sub 操作的文档。
  • regex: 要匹配的 Perl 兼容正则表达式。
  • replace: 匹配项中使用的替换字符串。
  • options (可选):用于定义如何执行 regex 匹配的选项。有关可用选项的详情,请查看 OpenResty Lua 模块项目文档中的 ngx.re.match 部分。
  • break (可选):如果命令设为 true(启用选中复选框),则该命令会重新识别该 URL,它将是最后应用的应用(列表中的所有 posterior 命令都将被丢弃)。

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

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

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

    • add:向现有参数添加值。
    • set:创建 arg(如果没有设置),并在设置时替换其值。
    • push:创建 arg(如果没有设置),并在设置时添加 值。
    • delete:删除 arg。
  • arg: 操作所应用到的查询参数名称。
  • value: 指定用于查询参数的值。对于值类型 "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. 查询参数 setarg 的值 original 替换为配置的值 setvalue
  5. add 命令没有应用,因为原始 URL 中不存在查询参数 addarg

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

4.1.32. 使用 Captures 重写 URL

URL 重写为 Captures 策略是 第 4.1.31 节 “URL 重写” 策略的替代选择,允许在将请求传递给 API 后端前重写 API 请求的 URL。

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

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

  • match_rule:此规则与传入请求 URL 匹配。它可以包含 {nameOfArgument} 格式的命名参数,这些参数可用于重写 URL。URL 以正则表达式的形式与 match_rule 进行比较。与指定参数匹配的值必须只包含以下字符(在 PCRE 正则表达式表示法中): [\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. 在管理门户中启用策略

执行以下步骤在管理门户中启用策略:

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

4.3. 创建自定义 APIcast 策略

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

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

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

4.4. 将自定义策略添加到 APIcast

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

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

如果创建了自定义策略,则必须将它们添加到 APIcast 中。您如何做到这一点取决于部署 APIcast 的位置:

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

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

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

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

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

警告

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

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

  1. 使用您在创建 registry 服务帐户中创建的凭证创建 docker-registry secret,如下所述:

    • 使用以 12345678|username 创建的用户名替换 your-registry-service-account-username
    • 使用用户名下面的密码字符串替换 your-registry-service-account-password,在 Token Information 标签页下。
    • 为每个镜像流所在的新 namespace 创建 docker-registry secret,并使用 registry.redhat.io

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

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

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

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

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

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

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

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

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

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

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

    oc new-app -f customizedApicast.yml
注意

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

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

4.5. 在 3scale 中创建策略链

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

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

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

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

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

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

  • 带有 id 值的 services 对象,用于指定策略链按数字应用到哪些服务
  • proxy 对象,其中包含 policy_chain 和后续对象
  • policy_chain 对象,其中包含定义策略链的值
  • 单个 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 置于策略链中的位置将影响策略行为。

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

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

THREESCALE_CONFIG_FILE=example.json bin/apicast

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

一些 第 4.1 节 “APIcast 标准策略” 支持 Liquid 模板,它不仅允许使用纯字符串值,也允许使用请求上下文中存在的变量。

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

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

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

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

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

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

  • jwt: JWT 令牌的解析 JSON 有效负载(用于 OpenID Connect 身份验证)。
  • credentials: 保存应用凭据的对象。示例: "app_id": "972f7b4f""user_key": "13b668c4d1e10eaebaa5144b4749713f"
  • service: 此对象保存处理当前请求的服务的配置。示例:服务 ID 将为 {{ service.id }}。

有关上下文中可用对象和值的完整列表,请查看 第 4.1.15 节 “移动上下文调试”

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

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

过滤器在变量输出标签 {{ }} 中,遵循变量的名称或竖线字符 | 和过滤器名称。示例:

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

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

过滤器可以按如下链接: {{ variable | function1 | function2 }}。示例: {{ '' | utctime | escape_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.7 上的 Fuse
  • 3scale 内部部署的 2.9
  • 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 集群上部署 Fuse on OpenShift 7.7 和 3scale 2.9。有关安装详情,请参阅:

  • 您必须具有集群管理员特权才能在 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 代理策略时,HTTP_SCHEMEHTTP_HOSTHTTP_PORTHTTP_PATH 标头的值根据 3scale 中为 backend API 配置的值自动设置。
    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

默认值 :no value : 字符串 示例http://forward-proxy:80

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

APICAST_ACCESS_LOG_FILE

默认 :stdout

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

APICAST_BACKEND_CACHE_HANDLER

:严格 | 弹性

默认 : strict

弃用 :改为使用 缓存 策略。

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

APICAST_CACHE_MAX_TIME

默认:1 m

值: 字符串

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

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

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

APICAST_CACHE_STATUS_CODES

默认: 200、302

值: 字符串

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

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

APICAST_CONFIGURATION_CACHE

:数字

默认 :0

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

APICAST_CONFIGURATION_LOADER

:boot | lazy

默认 : lazy

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

APICAST_CUSTOM_CONFIG

弃用 :改为使用 策略

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

APICAST_ENVIRONMENT

默认

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

默认值 :no 值

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

APICAST_HTTPS_CERTIFICATE_KEY

默认值 :no 值

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

APICAST_HTTPS_PORT

默认值 :no 值

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

APICAST_HTTPS_VERIFY_DEPTH

默认 :1

:正整数。

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

APICAST_LOAD_SERVICES_WHEN_NEEDED

值:

  • true 或者 1 用于 true
  • false0 或 empty for false

默认false

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

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

注意

APICAST_LOG_FILE

默认 : stderr

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

APICAST_LOG_LEVEL

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

默认 :warn

指定 OpenResty 日志的日志级别。

APICAST_MANAGEMENT_API

值:

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

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

APICAST_MODULE

默认 :apicast

弃用 :改为使用 策略

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

APICAST_OIDC_LOG_LEVEL

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

默认 :err

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

APICAST_PATH_ROUTING

  • true 或者 1 用于 true
  • false0 或 empty for false

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

APICAST_PATH_ROUTING_ONLY

  • true 或者 1 用于 true
  • false0 或 empty for false

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

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

APICAST_POLICY_LOAD_PATH

默认APICAST_DIR/policies

value: string[:]

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

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

APICAST_PROXY_HTTPS_CERTIFICATE

默认

:字符串

示例 :/home/apicast/my_certificate.crt

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

APICAST_PROXY_HTTPS_CERTIFICATE_KEY

默认

:字符串

示例 :/home/apicast/my_certificate.key

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

APICAST_PROXY_HTTPS_PASSWORD_FILE

默认

:字符串

示例 :/home/apicast/passwords.txt

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

APICAST_PROXY_HTTPS_SESSION_REUSE

默认 : on

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

APICAST_REPORTING_THREADS

默认 :0

:整数 >= 0

试验性 :了解高负载可能具有无法预计的性能并丢失报告。

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

APICAST_RESPONSE_CODES

  • true 或者 1 用于 true
  • false0 或 empty for false

默认 :<empty>(false)

当设置为 true 时,APIcast 将以 3scale 记录 API 后端返回的响应代码。在一些计划中,以后可以从 3scale 管理门户查看此信息。如需更多信息,请参阅 Response Code 跟踪

APICAST_SERVICE_CACHE_SIZE

:整数 >= 0

默认 : 1000

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

APICAST_SERVICE_${ID}_CONFIGURATION_VERSION

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

APICAST_SERVICES_LIST

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

用于过滤 3scale API Manager 中配置的服务,并且仅对网关中的特定服务使用配置,丢弃未在列表中指定的服务 ID。您可以在管理门户中找到服务 ID: Dashboard > [Your_API_name],标记为 API 调用的 ID

APICAST_SERVICES_FILTER_BY_URL

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

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

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

注意

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

例 7.1. 示例

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

数字 | auto

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

BACKEND_ENDPOINT_OVERRIDE

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

HTTP_KEEPALIVE_TIMEOUT

默认75 值 :正整数 示例 :1

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

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

HTTP_PROXY,HTTP_PROXY

默认值 :no value : 字符串 示例http://forward-proxy:80

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

HTTPS_PROXY,HTTPS_PROXY

默认值 :no value : 字符串 示例https://forward-proxy:443

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

NO_PROXY,NO_PROXY

default: no value : string\[,<string>\]; *示例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 支持。

解析器

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

THREESCALE_CONFIG_FILE

带有网关配置的 JSON 文件的路径。您可以使用以下 URL 从管理门户下载配置: <schema>://<admin-portal-domain>/admin/api/nginx/spec.json示例https://account-admin.3scale.net/admin/api/nginx/spec.json)。

使用 Docker 部署网关时,文件必须作为只读卷注入到 Docker 镜像中,并且路径应当指明卷的挂载位置,即 docker 容器的本地路径。

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

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

THREESCALE_DEPLOYMENT_ENV

: stage | production

默认 :production

环境变量的值定义特定配置的环境。使用新 APIcast 时,将从 3scale(标记或生产)下载该环境的配置。

THREESCALE_DEPLOYMENT_ENV 的值也用于授权的 X-3scale-User-Agent 标头中,并报告向 3scale 服务管理 API 发出的请求。标头值供 3scale 用于统计。

THREESCALE_PORTAL_ENDPOINT

以以下格式包含密码和门户端点的 URI: <schema>://<password>@<admin-portal-domain><password> 可以是 3scale 帐户管理 API 的供应商密钥或访问令牌。<admin-portal-domain> 是登录管理门户的 URL。

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

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

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

需要为 网关提供 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 毫秒。

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

Default caching behavior

8.3. 异步报告线程

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

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

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

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

Asynchronous reporting thread pool behavior

8.4. 3scale 批处理器策略

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

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

3scale Batcher policy behavior

第 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]

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

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

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

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

注意

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

9.2. APIcast 与 Prometheus 集成

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

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

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

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

9.2.1. 其他选项

另外,如果您有集群管理员访问 OpenShift 集群的权限,您可以扩展 total_response_time_secondsupstream_response_time_secondsupstream_status 指标来包含 service_idservice_system_name 标签。要扩展这些指标,请使用以下命令将 APICAST_EXTENDED_METRICS OpenShift 环境变量设置为 true

oc set env dc/apicast APICAST_EXTENDED_METRICS=true

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

注意

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

其他资源

有关 Prometheus 的信息,请参阅 Prometheus: Getting Started

9.3. 3scale APIcast 的 OpenShift 环境变量

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

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

环境变量描述默认

APICAST_EXTENDED_METRICS

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

  • total_response_time_seconds
  • upstream_response_time_seconds
  • upstream_status

false

其他资源

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

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

9.4. 3scale APIcast 指标公开给 Prometheus

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

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

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

指标描述类型标签

nginx_http_connections

HTTP 连接数

量表

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 共享字典的能力

量表

dict(每个字典对应一个。)

openresty_shdict_free_space

worker 共享字典的可用空间

量表

dict(每个字典对应一个。)

nginx_metric_errors_total

管理指标的 Lua 库错误数

计数

none

total_response_time_seconds

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

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

histogram

service_id, service_system_name

upstream_response_time_seconds

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

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

histogram

service_id, service_system_name

upstream_status

来自上游服务器的 HTTP 状态

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

计数

status, service_id, service_system_name

threescale_backend_calls

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

计数

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

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

指标描述类型标签

batching_policy_auths_cache_hits

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

计数

none

batching_policy_auths_cache_misses

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

计数

none

部分 II. API 版本控制

第 10 章 API 版本

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

10.1. 目标

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

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

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

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

10.2. 先决条件

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

10.3. URL 版本

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

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

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

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

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

图 10.1. 版本计划功能

Versioning Plan Feature

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

图 10.2. 将 URI 映射到指标

Mapping URIs to metrics

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

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

图 10.3. 版本控制

Versioning

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

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

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

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

图 10.4. 发送弃用备注

Sending deprecation note

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

10.4. 端点版本控制

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

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

外部

 

INTERNAL

api.songs.com/songwriter_v1

可被重写为

internal.songs.com/search_by_songwriter

api.songs.com/songwriter_v2

可被重写为

internal.songs.com/songwriter

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

10.5. 自定义标头版本

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

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

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

部分 III. API 身份验证

第 11 章 身份验证模式

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

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

11.1. 支持的验证模式

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

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

11.2. 设置身份验证模式

11.2.1. 选择服务的验证模式

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

Select Authentication Mode Step 1

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

重要

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

11.2.2. 选择要使用的 Authentication 模式

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

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

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

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

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

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

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

11.3. 标准验证模式

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

11.3.1. API 密钥

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

API-key = 853a76f7c8d5f4a1ee8bf10a4e0d1f13

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

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

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

11.3.2. App_ID 和 App_Key 对

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

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

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

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

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

11.3.3. OpenID Connect

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

11.4. 参考器过滤

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

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

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

Enable Referrer Filtering

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

Configure Referrers in the Developer Portal

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

Configure Referrers in the Developer Portal

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

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

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

  1. 没有指定推荐过滤器的应用程序通常只使用提供的凭证获得授权。
  2. 对于设置有引用器过滤器值的应用程序,APIcast 从请求的 Referer 标头中提取引用器值,并将它以 AuthRep(授权和报告)请求中的 referrer 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 请求,包括以下功能:

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

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

在这两种情况下,您可以使用 OpenID Connect 身份验证选项在服务的 Integration 页面上指定 OpenID Connect Issuer 字段来配置集成。具体步骤请查看 配置红帽单点登录集成

12.1. APIcast 验证和解析 JWT

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

Authorization: Bearer <JWK>

例如:

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

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

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

在每个请求中,APIcast 会执行以下操作:

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

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

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

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

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

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

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

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

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

先决条件

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

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

流程

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

    echo -n | openssl s_client -connect <rhsso_fqdn>:<rhsso_port> -servername <rhsso_fqdn> --showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > customCA.pem
  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 证书文件的内容附加到 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. 配置红帽单点登录

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

  1. 创建域(<REALM_NAME>)。
  2. 创建客户端:

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

    1. 访问类型confidential
    2. 标准流已启用OFF
    3. 支持 OFF 直接访问
    4. 启用至 ON 的服务帐户.
  4. 为客户端设置服务帐户角色:

    1. 导航到客户端的 Service Account Roles 选项卡。
    2. 客户端角色 下拉列表中,单击 realm-management
    3. Available Roles 窗格中,选择 manage-clients 列表项并通过点 Add selected >> 来分配角色。
  5. 请注意客户端凭证:

    1. 记录客户端 ID(<CLIENT_ID>)。
    2. 导航到客户端的 Credentials 选项卡,并记下 Secret 字段(<CLIENT_SECRET>)。
  6. 在域中添加用户:

    1. 单击窗口左侧的 Users 菜单。
    2. 单击 Add user
    3. 输入用户名,将 Email Verified 开关设置为 ON,然后点 Save
    4. Credentials 选项卡上,设置 密码。在两个字段中输入密码,将 Temporary 开关设置为 OFF 以避免在下次登录时重置密码,然后点击 Reset Password
    5. 显示弹出窗口时,单击 Change password

12.3.3. 配置 3scale

在 RH-SSO 中创建并配置了客户端后,您必须配置 3scale 才能使用 RH-SSO。

要配置 3scale,请执行以下步骤:

  1. 启用 OpenID Connect.

    1. 选择您要启用 OpenID Connect 身份验证的服务,导航到 [your_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 字段,使用您的 Red Hat Single Sign-On 服务器(位于主机 <RHSSO_HOST> 和端口 <RHSSO_PORT> )的 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. 先决条件

  • 启用 OIDC 作为验证模式,如 Configure 3scale所示
  • Zync
  • 与 Zync 集成,实现所选 IdP 和 3scale 之间的客户端同步

12.4.2. 流程

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

  1. 导航到 [Your_product_name] > Integration > Settings
  2. AUTHENTICATION 下,为任何 OAuth 2.0 流选择 OpenID Connect 使用 OpenID Connect。
  3. AUTHENTICATION SETTINGS 下指定 OpenID Connect(OIDC)基础知识

    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 颁发程序类型
  • http://id:secret@example.com/api 作为 OpenID Connect Issuer

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

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

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

所有端点都必须使用 2xx 状态代码进行回复。否则,3scale 会重试请求。

12.4.3.3. payload

创建和更新时的请求有效负载为 application/json:

{
  "client_id": "ee305610",
  "client_secret": "ac0e42db426b4377096c6590e2b06aed",
  "client_name": "oidc-app",
  "redirect_uris": ["http://example.com"],
  "grant_types": ["client_credentials", "password"]
}

删除客户端的请求没有有效负载。

12.4.3.4. 使用 OAuth2 身份验证

Zync 将 GET 请求发送到 /.well-known/openid-configuration 端点,并需要一个 application/json 响应。响应有效负载应包含以下内容:

{
  "token_endpoint": "http://idp.example.com/auth/realm/token"
}

使用 OAuth2 协议 时,Zync 使用 token_endpoint 来交换 OpenID Connect Issuer 地址中提供的 client_idclient_secret,以请求访问令牌。如果 API 响应不成功,Zync 将使用提供的凭据回退到 HTTP 基本/Digest 身份验证。

12.5. OAuth 2.0 支持的流

API 客户端必须使用此 OpenID 提供程序支持的任何 OAuth 2.0 流从 3scale 中配置的 OpenID Connect(OIDC)签发者获取访问令牌。如果是 RH-SSO,则支持以下流程(RH-SSO 客户端中使用的术语在括号中指定):

  • 授权代码(标准流
  • 资源所有者密码凭证(直接访问授予流
  • 隐式(影响流
  • 客户端凭据(服务帐户流

在 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 下,为任何 OAuth 2.0 流选择 OpenID Connect Use OpenID Connect。启用对应的流:

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

12.6. 测试集成

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

12.6.1. 测试客户端同步

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

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

12.6.2. 测试 API 授权流

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

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

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

12.7. 集成示例

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

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

在 3scale 中,有一个应用具有 myclientid 客户端 ID、myclientsecret 客户端 secret 和 https://myapp.example.com 重定向 URL。

在 RH- SSO 中,还有一个具有以下值的客户端:

  • 客户端 ID: myclientid
  • Secret: myclientsecret
  • 有效的重定向 URI: https://myapp.example.com

对于这个客户端,启用 Standard Flow。

myrealm 域中配置了具有 my user 用户名和 my password 密码的用户。

流程如下:

  1. 使用端点 https://idp.example.com/auth/realms/myrealm/protocol/openid-connect/auth,应用将授权请求发送到 RH-SSO。在请求中,应用程序提供以下参数: myclientid 客户端 ID 和 https://myapp.example.com 重定向 URL。
  2. RH-SSO 显示登录窗口,其中用户必须提供用户的凭据:Username myuser 和密码 mypassword
  3. 根据配置,如果这是用户首次在此特定应用中进行身份验证,则将显示同意窗口。
  4. 在用户通过身份验证后,applciation 使用端点 https://idp.example.com/auth/realms/myrealm/protocol/openid-connect/token 发送 Token 请求到 RH-SSO,并提供客户端 ID myclientid、客户端 secret myclientsecret 和重定向 URL https://myapp.example.com
  5. RH-SSO 返回带有"access_token"字段 eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArNhqF-A 的 JSON。
  6. 应用使用标头 Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk…​xBArNhqF-Ahttps://api.example.com 发送 API 请求。
  7. 该应用应该会收到来自 https://internal-api.example.com 的成功响应。