第 3 章 APIcast 策略


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

以下主题提供有关标准 APIcast 策略、创建策略链和创建自定义 APIcast 策略的信息。

3.1. 用于更改默认 3scale API 管理 APIcast 行为的标准策略

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

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

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

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

先决条件

  • 3scale API 产品。

流程

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

3.1.2. 3scale API 管理身份验证缓存

注意

始终将 auth 缓存策略放在策略链中的 APIcast 策略之前。

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

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

1.strict - Cache only authorized calls.

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

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

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

3.Allow - 当后端停机时,允许所有内容,除非在前和拒绝了。

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

重要

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

4.none - 禁用缓存。

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

配置属性

属性描述必需?

caching_type

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

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

策略对象示例

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

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

3.1.3. 3scale API 管理 Batcher

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

重要

要使用此策略,您必须在策略链中的 3scale Batcher 前放置 3scale Batcher。

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

3.1.4. 3scale API 管理推荐器

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

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

3.1.5. Anonymous Access(匿名访问)

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

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

注意

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

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

  • auth_type

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

    • app_id_and_app_key

      应用程序 ID/应用程序密钥身份验证选项:

    • user_key

      用于 API 密钥身份验证选项。

  • app_id (仅适用于 app_id_and_app_key 身份验证类型)

    API 调用中不提供任何凭据时将用于授权的应用程序的 App ID。

  • app_key (仅适用于 app_id_and_app_key 身份验证类型)

    API 调用中不提供任何凭据时将用于授权的应用的 App Key。

  • user_key (仅适用于 user_key auth_type)

    API 调用中不提供任何凭据时将用于授权的应用的 API 密钥。

图 3.1. 匿名访问策略

匿名访问策略

3.1.6. Camel Service

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

以下示例显示了流量流:

Camel 服务策略请求流

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

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

注意
  • 当域名解析为多个 IP 地址时,Camel 服务策略会禁用上游负载平衡 APIcast 功能。Camel 服务为上游服务管理 DNS 解析。
  • 如果定义了 HTTP_PROXYHTTPS_PROXYALL_PROXY 参数,此策略将覆盖这些值。
  • 代理连接不支持身份验证。您可以使用标头修改策略进行身份验证。

配置

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

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

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

使用案例示例

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

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

项目示例

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

3.1.7. 条件策略

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

重要

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

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

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

                             |
                             v

                          Headers

                             |
                             v

                       URL Rewriting

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

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

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

  1. APIcast
  2. Caching
  3. Upstream

Conditions

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

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

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

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

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

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

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

liquid 支持的变量

  • uri
  • 主机
  • remote_addr
  • headers['Some-Header']

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

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

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

3.1.8. 内容缓存

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

当内容缓存策略位于策略链中时,APIcast 会在发送上游请求前将 HEAD 请求发送到 GET 请求。如果您不想进行此转换,请不要将内容缓存策略添加到策略链中。

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

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

配置示例

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

支持的配置

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

上游响应标头

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

3.1.9. CORS 请求处理

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

  • 允许的标头
  • 允许的方法
  • 允许的源标头
  • 允许的凭证
  • 最长期限

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

注意

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

配置属性

属性描述必需?

allow_headers

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

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

allow_methods

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

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

allow_origin

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

数据类型:字符串

allow_credentials

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

数据类型:布尔值

max_age

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

数据类型:整数

策略对象示例

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

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

3.1.10. 自定义指标

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

自定义指标的限制

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

请求流示例

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

配置示例

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

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

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

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

3.1.11. Echo

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

配置属性

属性描述必需?

status

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

数据类型:整数

exit

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

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

策略对象示例

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

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

3.1.12. 边缘限制

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

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

限制类型

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

  • leaky_bucket_limiters

    基于泄漏 bucket 算法,它基于平均请求数加上最大突发大小。

  • fixed_window_limiters

    根据固定的时间窗口:最后 n 秒。

  • connection_limiters

    基于连接的并发数量。

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

限制定义

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

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

  • name

    定义密钥的名称。它在范围内必须是唯一的。

  • scope

    定义密钥的范围。支持的范围有:

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

    • 纯文本(plain
    • Liquid(liquid

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

  • leaky_bucket_limiters

    速率突发.

    • rate

      定义可以在不延迟的情况下每秒发出多少个请求。

    • burst

      定义每秒的请求量可能超过允许的速率。为超过由 rate 指定的允许费率的请求引入人为延迟。在超过 burst 中定义的每秒请求数后,请求将被拒绝。

  • fixed_window_limiters

    计算窗口.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
    }

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

移动模板

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

示例

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

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

应用条件

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

condition 由以下属性定义:

  • combine_op

    应用到操作列表的布尔值运算符。支持 orand

  • 操作

    需要评估的条件列表。每个操作都由一个具有以下属性的对象表示:

    • left

      操作的左侧部分.

    • left_type

      如何评估 left 属性(名文或 liquid)。

    • right

      操作的右侧部分.

    • right_type

      如何评估 right 的属性(名文或 liquid)。

    • op

      Operator 在左侧和右侧部分之间应用。支持以下两个值: == (等于)和 != (不等于)。

示例

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

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

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

错误处理

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

  • limits_exceeded_error

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

    • status_code

      超过限值时请求的状态代码。默认:429

    • error_handling

      使用以下选项指定如何处理错误:

      • exit

        停止处理请求并返回错误消息。

      • log

        完成处理请求并返回输出日志。

  • configuration_error

    指定在配置不正确时将返回到客户端的错误状态代码和消息。应配置以下参数:

    • status_code

      存在配置问题时的状态代码。默认:500

    • error_handling

      使用以下选项指定如何处理错误:

      • exit

        停止处理请求并返回错误消息。

      • log

        完成处理请求并返回输出日志。

3.1.13. 标头修改

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

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

  • Request (请求)

    要应用到请求标头的操作列表

  • 响应

    应用到响应标头的操作列表

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

  • op :指定要应用的操作。add 操作会为现有标头添加一个值。这个 set 操作会创建一个标头和值,如果已存在该标头的值,则会覆盖现有的标头值。push 操作会创建一个标头和值,但如果已存在,则不会覆盖现有的标头值。相反,push 会将值添加到现有标头中。delete 操作会删除标头。
  • header :指定要创建或修改的标头,可以是可用作标头名称的任何字符串,如 Custom-Header
  • value_type :定义如何评估标头值,可以是 plain (纯文本)或 liquid (作为 Liquid 模板评估)。更多信息请参阅 第 4.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 API 管理 部分创建策略链。

3.1.14. HTTP 状态代码覆盖

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

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

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

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

在管理门户中添加 HTTP Status Code Overwrite 策略的一种替代方案是将 3scale API 与策略链配置文件搭配使用。

示例

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

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

3.1.15. HTTP2 端点

HTTP2 端点策略启用发送请求和 APIcast 的消费者应用之间的 HTTP/2 协议和远程过程调用(gRPC)连接。当 HTTP2 端点策略位于产品的策略链中时,整个通信流(从向上游服务发出请求的消费者应用程序到 APIcast)可以使用 HTTP/2 协议和 gRPC。

当 HTTP2 端点策略位于策略链中时:

  • 请求身份验证必须是 JSON Web 令牌或 App_IDApp_Key 对的方法。不支持 API 密钥身份验证。
  • gRPC 端点终止传输层安全(TLS)。
  • HTTP2 端点策略必须在 3scale APIcast 策略之前。
  • 上游服务的后端可以实施 HTTP/1.1 纯文本或传输层安全(TLS)。
  • 策略链还必须包含 TLS 终止策略。

    APIcast 配置策略链示例:

    "policy_chain": [
      { "name": "apicast.policy.tls" },
      { "name": "apicast.policy.grpc" },
      { "name": "apicast.policy.apicast" }
    ]

3.1.16. IP 检查

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

配置属性

属性描述数据类型必需?

check_type

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

字符串,必须是 whitelistblacklist

ips

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

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

error_msg

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

字符串

client_ip_sources

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

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

策略对象示例

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

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

3.1.17. JWT 申索检查

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

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

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

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

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

配置策略

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

    单击对应部分中的加号 + 图标,您可以添加更多资源类型和允许的方法。

  11. 单击 Update Policy Chain 以保存您的更改。

3.1.18. Liquid Context Debug

注意

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

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

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

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

3.1.19. 日志记录

Logging 策略有两个目的:

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

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

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

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

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

3.1.19.1. 为所有 API 配置日志策略

APICAST_ENVIRONMENT 可用于加载使策略全局应用到所有 API 产品的配置。以下是如何实现此目标的示例。APICAST_ENVIRONMENT 用于指向文件的路径,这取决于部署、模板或操作器的类型。

要在全局范围内配置日志记录策略,根据您的部署类型考虑以下内容:

  • 对于基于模板的部署:需要通过 ConfigMap 和 VolumeMount 将文件挂载到容器中。
  • 对于 3scale 基于 operator 的部署:

    • 在 3scale 2.11 及以前的版本中,需要通过 ConfigMap 和 VolumeMount 将文件挂载到容器中。
    • 从 3scale 2.11 开始,需要使用 APIManager 自定义资源(CR)中引用的 secret。
  • 对于 APIcast operator 部署:

    • 在以前的版本中 3scale 2.11 无法配置它。
    • 从 3scale 2.11 开始,需要使用 APIManager CR 中引用的 secret。
  • 对于在 Docker 上部署的 APIcast 自我管理,需要将文件挂载到容器。

日志记录选项有助于避免出现 API 中未正确格式化的日志问题。

以下是在所有服务中载入的策略示例:

custom_env.lua file

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

3.1.19.1.1. 通过在容器中通过 ConfigMap 和 VolumeMount 挂载文件系统来配置所有 API 的日志记录策略
  1. 使用 custom_env.lua 文件创建 ConfigMap:

    $ oc create configmap logging --from-file=/path/to/custom_env.lua
  2. 为 ConfigMap 挂载一个卷,如 apicast-staging

    $ oc set volume dc/apicast-staging --add --name=logging --mount-path=/opt/app-root/src/config/custom_env.lua --sub-path=custom_env.lua -t configmap --configmap-name=logging
  3. 设置环境变量:

    $ oc set env dc/apicast-staging APICAST_ENVIRONMENT=/opt/app-root/src/config/custom_env.lua
3.1.19.1.2. 使用 APIManager CR 中引用的 secret 配置日志记录策略

基于 operator 的部署中从 3scale 2.11 开始,将日志策略配置为 secret,并在 APIManager CR 中引用 secret。

注意

以下流程只适用于 3scale Operator。但是,您可以使用这些步骤以类似的方式配置 APIcast operator。

先决条件

  • 一个或多个使用 Lua 的代码定制的环境。

流程

  1. 使用自定义环境内容创建 secret:

    $ oc create secret generic custom-env --from-file=./custom_env.lua
  2. 使用 APIcast 自定义环境配置和部署 APIManager CR:

    apimanager.yaml content:

    apiVersion: apps.3scale.net/v1alpha1
    kind: APIManager
    metadata:
      name: apimanager-apicast-custom-environment
    spec:
      apicast:
        productionSpec:
          customEnvironments:
            - secretRef:
                name: custom-env
        stagingSpec:
          customEnvironments:
            - secretRef:
                name: custom-env

  3. 部署 APIManager CR:

    $ oc apply -f apimanager.yaml

如果 secret 不存在,Operator 会将 CR 标记为失败。对 secret 的更改将需要重新部署 pod/容器才能反映在 APIcast 中。

更新自定义虚拟环境

如果您需要修改自定义环境内容,有两个选项:

  • 建议:使用不同的名称创建另一个 secret 并更新 APIManager CR 字段:

    customEnvironments[].secretRef.name

    Operator 会触发滚动更新载入新的自定义环境内容。

  • 更新现有的 secret 内容,并重新部署 APIcast 将 spec.apicast.productionSpec.replicasspec.apicast.stagingSpec.replicas 设置为 0, 然后切换到以前的值。
3.1.19.1.3. 为 Docker 上部署的 APIcast 自我管理的所有 API 配置日志策略

使用以下 docker 命令挂载 custom_env.lua 来运行 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 文件。

3.1.19.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.serializable.name}}",
  }
}

使用 JSON 格式配置访问日志

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

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

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

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

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

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

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

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

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

    • THREESCALE_CONFIG_FILE
    • THREESCALE_PORTAL_ENDPOINT

3.1.20. 维护模式

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

配置属性

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

属性valuedefault描述

status

整数,可选

503

响应代码

message

字符串,可选

503 服务不可用 - 维护

响应消息

维护模式策略示例

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

为特定上游应用维护模式

{
    "name": "maintenance_mode",
    "version": "builtin",
    "configuration": {
        "message_content_type": "text/plain; charset=utf-8",
        "message": "Echo API /test is currently Unavailable",
        "condition": {
            "combine_op": "and",
            "operations": [
                {
                    "left_type": "liquid",
                    "right_type": "plain",
                    "op": "==",
                    "left": "{{ original_request.path }}",
                    "right": "/test"
                }
            ]
        },
        "status": 503
    }
}

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

3.1.21. NGINX Filter

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

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

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

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

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

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

重要

标头修改策略 和 NGINX 过滤器策略指定相同的标头是潜在的冲突来源。

3.1.22. 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": { }
  }
}

3.1.23. OAuth 2.0 令牌内省

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

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

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

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

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

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

      验证类型设置为 client_id+client_secret:

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

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

OAuth 2.0 令牌内省配置

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

  • true

    调用已授权

  • false

    该调用被拒绝,并显示 Authentication Failed 错误

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

3.1.24. On Fail

作为 API 供应商,您可以将 On Fail 策略添加到 API 产品中。当 On Fail 策略位于策略链中,并且针对给定的 API 使用者请求执行策略会失败,APIcast 执行以下操作:

  • 停止处理请求。
  • 将您指定的状态代码返回到发送请求的应用程序,

当 APIcast 无法处理策略时,On Fail 策略很有用,这可能是因为配置不正确,或因为自定义策略中不合规的代码。如果没有策略链中的 On Fail 策略,APIcast 会跳过它无法应用的策略,在链中处理任何其他策略,并将请求发送到上游 API。在策略链中使用 On Fail 策略,APIcast 拒绝请求。

在策略链中,On Fail 策略可以处于任何位置。

在管理门户中,将 On Fail 策略添加到产品的策略链中。在策略链中,点策略指定您希望 APIcast 在应用 On Fail 策略时返回的状态代码。例如,您可以指定 400,这表示来自客户端的错误请求。

3.1.25. 代理服务

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

以下示例显示了流量流:

代理服务策略请求流

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

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

注意
  • * Camel 服务策略当域名解析为多个 IP 地址时,禁用上游负载平衡的 APIcast 功能。Camel 服务为上游服务管理 DNS 解析。
  • 如果定义了 HTTP_PROXYHTTPS_PROXYALL_PROXY 参数,此策略将覆盖这些值。
  • 代理连接不支持身份验证。您可以使用标头修改策略进行身份验证。

配置

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

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

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

使用案例示例

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

项目示例

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

3.1.26. 速率限制标头

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

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

RateLimit 标头

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

  • RateLimit-Limit

    在配置的时间窗口中显示请求总数,例如 10 个请求。

  • ratelimit-Remaining

    在当前时间窗口中显示剩余的请求配额,例如 5 个请求。

  • RateLimit-Reset

    在当前时间窗口中显示剩余的秒数,例如 30 秒。此标头的行为与 Retry-After 标头的 delta-seconds 表示法兼容。

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

注意

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

3.1.27. 响应/请求内容限制

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

此策略有助于防止过载:

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

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

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

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

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

3.1.28. Retry

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

重要

从 3scale 2.14 开始,无法配置从策略重试的情况。这通过环境变量 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
      }
    }
  }
}

3.1.29. RH-SSO/Keycloak 角色检查

注意

当您将 RH-SSO/Keycloak 角色检查策略添加到 APIcast 策略链中时,将其放在 APIcast 和路由策略之前。

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

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

  • whitelist

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

  • blacklist

    使用 blacklist 时,如果 JWT 令牌包含黑名单范围,APIcast 将拒绝调用。

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

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

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

  • resource

    由角色控制的资源端点。这个格式与映射规则相同。模式从字符串开头匹配,若要完全匹配,您必须在末尾附加 $

  • resource_type

    这可定义如何评估 resource 值。

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

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

    使用它检查 realm 角色。请参阅红帽单点登录文档中的 Realm 角色

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

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

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

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

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

    • name

      指定角色的名称。

    • name_type

      定义如何评估名称;值可以是 plain,也可以是 liquid。其工作方式与 resource_type 相同。

  • client_roles

    使用 client_roles 检查客户端命名空间中的特定访问角色。请参阅红帽单点登录文档中的客户端角色

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

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

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

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

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

    • name

      指定角色的名称。

    • name_type

      定义如何评估 name 值;该值可以是 plain 值,也可以是 liquid 值。其工作方式与 resource_type 相同。

    • client

      指定角色的客户端。如果未定义,此策略将 aud 声明用作客户端。

    • client_type

      定义如何评估 client 值;值可以是 plain 值或 liquid 值。其工作方式与 resource_type 相同。

3.1.30. 路由

注意

即使路由策略处理请求时,也必须仍存在针对请求的对应映射规则。

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

重要

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

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

路由规则

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

请求路径规则

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

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

标头规则

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

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

查询参数规则

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

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

JWT 声明规则

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

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

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

多操作规则

只有当所有上游都使用 'and' combined_op 评估为 true 时,或者当其中至少一个规则通过使用 'or' combine_op 评估为 true 时,规则可以有多个操作并路由到给定上游。combine_op 的默认值为 'and'。

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

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

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

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

组合规则

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

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

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

catch-all 规则

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

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

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

支持的操作

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

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

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

移动模板

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

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

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

设置 host_header中使用的主机

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

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

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

3.1.31. SOAP

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

配置属性

属性描述必需?

pattern

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

数据类型:字符串

metric_system_name

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

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

策略对象示例

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

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

3.1.32. TLS 客户端证书验证

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

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

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

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

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

设置 APIcast 以使用策略

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

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

    注意

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

另外:

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

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

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

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

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

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

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

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

从白名单中删除证书

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

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

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

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

3.1.33. TLS 终止

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

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

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

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

在策略链中配置 TLS 终止

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

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

按照以下步骤操作:

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

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

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

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

另外:

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

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

验证 TLS 终止策略的功能

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

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

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

其中:

  • public_URL

    暂存公共基本 URL。

  • port

    端口号。

  • user_key

    要进行身份验证的用户密钥。

  • path_to_certificate

    到本地文件系统中的 CA 证书的路径。

从 TLS 终止中删除文件

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

删除证书:

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

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

3.1.34. Upstream

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

例如:

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

策略链参考:

属性描述必需?

regex

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

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

url

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

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

策略对象示例

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

      }
    ]
  }
}

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

3.1.35. 上游连接

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

  • proxy_connect_timeout
  • proxy_send_timeout
  • proxy_read_timeout

配置上游连接策略:

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

按照以下步骤操作:

  1. 要将 Upstream Connection 策略添加到您的 API 中,请按照 3scale API 管理管理门户中启用策略 中所述的步骤,然后选择 Upstream Connection
  2. 单击 Upstream Connection 链接。
  3. 若要启用该策略,选中 Enabled 复选框。
  4. 配置与上游连接的选项:

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

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

3.1.36. Upstream Mutual TLS

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

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

注意

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

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

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

    • path

      如果要指定证书的路径,如 OpenShift 生成的证书的路径。

    • embedded

      如果要使用第三方生成的证书,请通过从您的文件系统上传证书。

  5. Certificate 中,指定客户端证书。
  6. Certificate key 中指定密钥。
  7. 使用 Upstream Mutual TLS 设置完 API 后,点 Update Policy Chain

推进您的更改:

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

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

路径配置

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

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

嵌入式配置

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

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

有关 Upstream Mutual TLS 的其他字段 ca_certificatesverify策略配置模式 的详细。

其他注意事项

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

3.1.37. URL Rewriting

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

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

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

  • commands

    要应用的命令列表来重写请求的路径。

  • query_args_commands

    要应用的命令列表,用于重写请求的查询字符串。

重写路径的命令

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

  • op

    要应用的操作。可用的选项包括:subgsubsub 操作仅用您指定的正则表达式替换第一个匹配项。gsub 操作会将所有匹配项替换为您指定的正则表达式。请参阅有关 subgsub 操作的文档。

  • regex

    要匹配 Perl 的正则表达式。

  • replace

    匹配项时使用的替换字符串。

  • options

    这是可选的。定义如何执行 regex 匹配的选项。有关可用选项的详情,请查看 OpenResty Lua 模块项目文档中的 ngx.re.match 部分。

  • break

    这是可选的。当启用复选框设置为 true 时,如果命令重新编写该 URL,它将是应用的最后一个,并且列表中的所有 posterior 命令将被丢弃。

重写查询字符串的命令

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

  • op

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

    • add

      为现有参数添加一个值。

    • set

      创建 arg(如果没有设置),并在设置时替换其值。

    • push

      创建 arg(如果没有设置),并在设置时添加值。

    • delete

      删除 arg。

  • arg

    操作所应用的查询参数名称。

  • value

    指定用于查询参数的值。对于值类型"liquid",值应当采用 {{ variable_from_context }} 格式。对于 delete 操作,不考虑该值。

  • value_type

    这是可选的。定义如何评估查询参数值,可以是 plain (纯文本)或 liquid (用于 Liquid 模板)。更多信息请参阅 第 4.1 节 “在策略中使用变量和过滤器”。如果没有指定,则默认使用类型"plain"。

示例

URL 重写策略配置如下:

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

发送到 APIcast 的原始请求 URI:

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

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

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

应用以下转换:

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

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

3.1.38. 使用 Captures 重写 URL

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

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

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

  • match_rule

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

  • 模板

    使用重写原始 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

3.1.39. WebSocket

WebSocket 策略启用 WebSocket 协议连接到上游 API。如果您计划启用 WebSocket 协议,请考虑以下几点:

  • WebSocket 协议不允许额外的标头。

    • 使用凭证位置的查询参数配置 WebSocket 策略。
    • WebSocket 策略不支持 OpenID Connect (OIDC)身份验证方法。
  • WebSocket 协议不属于 HTTP/2 标准。

对于启用了 WebSocket 连接的给定上游 API,您可以将其后端定义为 http[s]ws[s]

如果将 WebSocket 策略添加到策略链中,请确保它位于 3scale API 管理 APIcast 策略之前。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.