1.20. 使用 3scale WebAssembly 模块

注意

threescale-wasm-auth 模块在 3scale API 管理 2.11 或更高版本与 Red Hat OpenShift Service Mesh 2.1.0 或更高版本的集成时运行。

threescale-wasm-auth 模块是一个 WebAssembly 模块,它使用一组接口,称为应用二进制接口(ABI)。这由 Proxy-WASM 规范定义,驱动实施 ABI 的任何软件,以便它能够授权 HTTP 请求针对 3scale。

作为 ABI 规范,Proxy-WASM 定义名为 host 的软件与另一个命名 模块程序扩展 名之间的交互。主机公开一组供模块用于执行任务的服务,本例中用于处理代理请求。

主机环境由 WebAsembly 虚拟机组成,与软件进行交互,本例中为 HTTP 代理。

模块本身与外部世界隔离运行,除了它在虚拟机上运行的指令和 Proxy-WASM 指定的 ABI 除外。这是为软件提供扩展点的安全方法:扩展只能以明确定义的方式与虚拟机和主机进行交互。该交互提供了一种计算模型和与代理旨在具有的外部的连接。

1.20.1. 兼容性

threescale-wasm-auth 模块设计为与 Proxy-WASM ABI 规范的所有实施完全兼容。然而,此时只经过了全面测试才能与 Envoy 反向代理配合使用。

1.20.2. 使用作为独立模块

由于其自包含的设计,可以将此模块配置为与独立于 Service Mesh 的 Proxy-WASM 代理以及 3scale Istio 适配器部署配合使用。

1.20.3. 先决条件

  • 模块适用于所有支持的 3scale 版本,但在将服务配置为使用 OpenID 连接(OIDC) 时(需要 3scale 2.11 或更高版本)。

1.20.4. 配置 threescale-wasm-auth 模块

OpenShift Container Platform 上的集群管理员可以配置 threescale-wasm-auth 模块,通过应用程序二进制接口(ABI)授权 HTTP 请求进行 3scale API 管理。ABI 定义主机和模块之间的交互,公开主机服务,并允许您使用模块来处理代理请求。

1.20.4.1. Service Mesh 扩展

Service Mesh 提供了一个 自定义资源定义 来指定并应用 Proxy-WASM 扩展到 sidecar 代理,称为 ServiceMeshExtension。Service Mesh 将此自定义资源应用到需要使用 3scale 管理 HTTP API 的工作负载集合。

注意

配置 WebAssembly 扩展目前是一个手动过程。以后的发行版本中将提供对 3scale 系统获取服务配置的支持。

先决条件

  • 识别要应用此模块的 Service Mesh 部署上的 Kubernetes 工作负载和命名空间。
  • 您必须有一个 3scale 租户帐户。请参阅 SaaS3scale 2.11 On-Premises,其中定义了匹配的服务和相关应用程序和指标。
  • 如果您在 bookinfo 命名空间中将模块应用到 productpage 微服务,请参阅 Bookinfo 示例应用程序

    • 以下示例是 threescale-wasm-auth 模块的自定义资源的 YAML 格式。这个示例指的是 Service Mesh 的上游 Maistra 版本 ServiceMeshExtension API。您必须声明部署 3scale-wasm-auth 模块的命名空间,以及一个 WorkloadSelector,以标识该模块将应用到的应用程序集:

      apiVersion: maistra.io/v1
      kind: ServiceMeshExtension
      metadata:
        name: threescale-wasm-auth
        namespace: bookinfo 1
      spec:
        workloadSelector: 2
          labels:
            app: productpage
        config: <yaml_configuration>
        image: registry.redhat.io/openshift-service-mesh/3scale-auth-wasm-rhel8:0.0.1
        phase: PostAuthZ
        priority: 100
      1
      namespace
      2
      WorkloadSelector
  • spec.config 字段取决于模块配置,并且没有填充到上例中。这个示例使用 <yaml_configuration> 占位符值。您可以使用此自定义资源示例的格式。

    • spec.config 字段因应用程序而异。所有其他字段在该自定义资源的多个实例之间都存在。例如:

      • Image:仅在部署较新版本的模块时更改。
      • phase :保留相同的模块,因为此模块需要在代理完成任何本地授权后调用,如验证 OpenID Connect(OIDC)令牌。
  • spec.config 和其余自定义资源中配置了模块后,使用 oc apply 命令应用它:

    $ oc apply -f threescale-wasm-auth-bookinfo.yaml

1.20.5. 应用 3scale 外部 ServiceEntry 对象

要让 threescale-wasm-auth 模块授权针对 3scale 的请求,该模块必须有权访问 3scale 服务。您可以通过应用外部 ServiceEntry 对象和用于 TLS 配置的对应的 DestinationRule 对象来在 Red Hat OpenShift Service Mesh 中执行此操作,以使用 HTTPS 协议。

自定义资源(CR)设置服务条目和目的地规则,以便从 Service Mesh 内安全访问 3scale 托管(SaaS),用于服务管理 API 和帐户管理 API 的后端和系统组件。Service Management API 接收每个请求的授权状态查询。帐户管理 API 为您的服务提供 API 管理配置设置。

流程

  1. 对集群的由 3scale 托管的后端应用以下外部 ServiceEntry CR 和相关的 DestinationRule CR:

    1. ServiceEntry CR 添加到名为 service-entry-threescale-saas-backend.yml 的文件:

      ServiceEntry CR

      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: service-entry-threescale-saas-backend
      spec:
        hosts:
        - su1.3scale.net
        ports:
        - number: 443
          name: https
          protocol: HTTPS
        location: MESH_EXTERNAL
        resolution: DNS

    2. DestinationRule CR 添加到名为 destination-rule-threescale-saas-backend.yml 的文件:

      DestinationRule CR

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: destination-rule-threescale-saas-backend
      spec:
        host: su1.3scale.net
        trafficPolicy:
          tls:
            mode: SIMPLE
            sni: su1.3scale.net

    3. 运行以下命令,为 3scale 托管后端应用并保存外部 ServiceEntry CR:

      $ oc apply -f service-entry-threescale-saas-backend.yml
    4. 运行以下命令,为 3scale Hosted 后端应用并保存外部 DestinationRule CR:

      $ oc apply -f destination-rule-threescale-saas-backend.yml
  2. 对集群的由 3scale 托管的系统应用以下外部 ServiceEntry CR 和相关的 DestinationRule CR:

    1. ServiceEntry CR 添加到名为 service-entry-threescale-saas-system.yml 的文件:

      ServiceEntry CR

      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: service-entry-threescale-saas-system
      spec:
        hosts:
        - multitenant.3scale.net
        ports:
        - number: 443
          name: https
          protocol: HTTPS
        location: MESH_EXTERNAL
        resolution: DNS

    2. DestinationRule CR 添加到名为 destination-rule-threescale-saas-system.yml 的文件:

      DestinationRule CR

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: destination-rule-threescale-saas-system
      spec:
        host: multitenant.3scale.net
        trafficPolicy:
          tls:
            mode: SIMPLE
            sni: multitenant.3scale.net

    3. 运行以下命令,为 3scale 托管系统应用并保存外部 ServiceEntry CR:

      $ oc apply -f service-entry-threescale-saas-system.yml
    4. 运行以下命令,为 3scale Hosted 系统应用并保存外部 DestinationRule CR:

      $ oc apply -f <destination-rule-threescale-saas-system.yml>

或者,您可以部署一个mesh 3scale 服务。要部署 in-mesh 3scale 服务,请通过部署 3scale 并链接到部署来更改 CR 中服务的位置。

1.20.6. 3scale WebAssembly 模块配置

ServiceMeshExtension 自定义资源规格提供了 Proxy-WASM 模块从中读取的配置。

该 spec 嵌入主机中,并由 Proxy-WASM 模块读取。通常,配置采用要解析的模块的 JSON 文件格式,但 ServiceMeshExtension 资源可以将 spec 值解释为 YAML,并将其转换为 JSON 以供模块使用。

如果您在独立模式中使用 Proxy-WASM 模块,则必须使用 JSON 格式编写配置。使用 JSON 格式意味着在 host 配置文件中根据需要使用转义和引用,如 Envoy。当您将 WebAssembly 模块与 ServiceMeshExtension 资源搭配使用时,配置采用 YAML 格式。在这种情况下,无效的配置会强制模块根据其 JSON 表示将诊断显示到 sidecar 的日志记录流。

重要

EnvoyFilter 自定义资源不是受支持的 API,虽然可在 3scale Istio 适配器或 Service Mesh 版本中使用。不建议使用 EnvoyFilter 自定义资源。使用 ServiceMeshExtension API 而不是 EnvoyFilter 自定义资源。如果需要使用 EnvoyFilter 自定义资源,则必须以 JSON 格式指定 spec。

1.20.6.1. 配置 3scale WebAssembly 模块

3scale WebAssembly 模块配置的架构取决于 3scale 帐户和授权服务,以及要处理的服务列表。

先决条件

在所有情形中,先决条件都是一组最低必填字段:

  • 对于 3scale 帐户和授权服务:backend-listener URL。
  • 要处理的服务列表:服务 ID 和至少一个凭据查找方法以及查找方法。
  • 您将找到处理 userkey、以及带有 appkeyappid,以及 OpenID Connect(OIDC)模式的示例。
  • WebAssembly 模块使用您在静态配置中指定的设置。例如,如果您向模块中添加映射规则配置,它将始终适用,即使 3scale 管理门户没有这样的映射规则。ServiceMeshExtension 资源的其余部分围绕 spec.config YAML 条目存在。

1.20.6.2. 3scale WebAssembly 模块 api 对象

3scale WebAssembly 模块的 api 顶级字符串定义模块要使用的配置版本。

注意

api 对象的不存在或不受支持的版本会导致 3scale WebAssembly 模块无法正常运行。

api 顶级字符串示例

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
  namespace: bookinfo
spec:
  config:
    api: v1
...

api 条目定义配置的其余值。唯一接受的值是 v1。破坏与当前配置兼容性或需要更多使用 v1 的模块无法处理的逻辑的新设置将需要不同的值。

1.20.6.3. 3scale WebAssembly 模块系统对象

system 顶级对象指定如何访问特定帐户的 3scale 帐户管理 API。upstream 字段是对象最重要的部分。upstream 对象是可选的,但建议使用,除非您要为 3scale WebAssembly 模块提供完全静态的配置,如果您不想提供到 3scale 的 system 组件的连接,则此选项是一个选项。

当您在 system 对象之外提供静态配置对象时,静态配置对象始终优先。

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  ...
  config:
    system:
      name: saas_porta
      upstream: <object>
      token: myaccount_token
      ttl: 300
  ...

表 1.23. system 对象字段

名称描述必填

name

3scale 服务的标识符,目前没有在别处引用。

选填

upstream

要联系的网络主机的详细信息。upstream 代表 3scale 帐户管理 API 主机,称为 system。

token

具有读取权限的 3scale 个人访问令牌。

ttl

在尝试获取新更改之前,将从此主机检索到的配置视为有效的最少秒数。默认为 600 秒(10 分钟)。注意:没有最大值,但模块通常会在此 TTL apsaps 之后合理时间段内获取任何配置。

选填

1.20.6.4. 3scale WebAssembly 模块上游对象

upstream 对象描述代理可以对其执行调用的外部主机。

apiVersion: maistra.io/v1
upstream:
  name: outbound|443||multitenant.3scale.net
  url: "https://myaccount-admin.3scale.net/"
  timeout: 5000
...

表 1.24. upstream 对象字段

名称描述必填

name

name 不是自由格式的标识符。它是外部主机的标识符,如代理配置中所定义。对于独立 Envoy 配置,它会映射到一个集群的名称,在其他代理中也称为 上游(upstream)注: 这个字段的值,因为 Service Mesh 和 3scale Istio 适配器 control plane 根据使用竖线(|)作为多个字段分隔符的格式来配置名称。对于此集成,请始终使用格式:outbound|<port>||<hostname>

url

用于访问所描述服务的完整 URL。除非被方案所暗示,否则您必须包含 TCP 端口。

Timeout(超时)

超时时间(毫秒),使得响应时间超过响应时间的连接将被视为错误。默认值为 1000 秒。

选填

1.20.6.5. 3scale WebAssembly 模块后端对象

backend 顶级对象指定如何访问 3scale Service Management API 来授权和报告 HTTP 请求。此服务由 3scale 的 Backend 组件提供。

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  config:
    ...
    backend:
      name: backend
      upstream: <object>
    ...

表 1.25. backend 对象字段

名称描述必填

name

3scale 后端的标识符,目前没有在别处引用。

选填

upstream

要联系的网络主机的详细信息。这必须引用 3scale 帐户管理 API 主机,即已知系统。

是。最重要和必填字段。

1.20.6.6. 3scale WebAssembly 模块服务对象

services 顶级对象指定由 module 的特定实例处理哪些服务标识符。

由于帐户具有多个服务,您必须指定处理哪些服务。其余的配置会围绕如何配置服务。

services 字段是必需的。它是必须至少包含一个服务的数组,才可使用。

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  config:
    ...
    services:
    - id: "2555417834789"
      token: service_token
      authorities:
        - "*.app"
        - 0.0.0.0
        - "0.0.0.0:8443"
      credentials: <object>
      mapping_rules: <object>
    ...

services 数组中的每个元素代表 3scale 服务。

表 1.26. services 对象字段

名称描述必需

ID

此 3scale 服务的标识符,目前没有在别处引用。

token

token 可以在您的系统中的服务的代理配置中找到,也可以使用以下 curl 命令从系统检索它:

curl https://<system_host>/admin/api/services/<service_id>/proxy/configs/production/latest.json?access_token=<access_token>" | jq '.proxy_config.content.backend_authentication_value

authorities

一个字符串数组,每个字符串代表要匹配的 URL颁发机构。这些字符串接受支持星号(*)加号(+)和问号(?)匹配器的 glob 模式。

credentials

定义要查找和在哪里查找的凭据的对象。

mapping_rules

代表要命中映射规则和 3scale 方法的一组对象。

1.20.6.7. 3scale WebAssembly 模块凭证对象

credentials 对象是 service 对象的组件。credentials 指定要查找的凭证类型,以及执行此操作的步骤。

所有字段均为可选,但您必须至少指定一个 user_keyapp_id。指定每个凭据的顺序无关紧要,因为它由模块预先建立。仅指定每个凭证的一个实例。

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  config:
    ...
    services:
    - credentials:
        user_key: <array_of_lookup_queries>
        app_id: <array_of_lookup_queries>
        app_key: <array_of_lookup_queries>
    ...

表 1.27. credentials 对象字段

名称描述必需

user_key

这是一组查询,用于定义 3scale 用户密钥。用户密钥通常称为 API 密钥。

选填

app_id

这是一组查询,用于定义 3scale 应用标识符。应用程序标识符由 3scale 提供,或使用 Red Hat Single Sign-On (RH-SS0) 或 OpenID Connect(OIDC)等身份提供程序来提供。此处指定的查找查询的解析(只要成功并解析为两个值),它会设置 app_idapp_key

选填

app_key

这是一组用于定义 3scale 应用键的查询。没有解析的 app_id 的应用程序密钥是无用的,因此仅在指定 app_id 时指定此字段。

选填

1.20.6.8. 3scale WebAssembly 模块查找查询

lookup query 对象是 credentials 对象中任何字段的一部分。它指定如何查找和处理给定凭证字段。评估之后,成功解析意味着找到一个或多个值。失败的解决方案意味着没有找到任何值。

lookup queries 的数组描述了一个短电路或关系:成功解析其中一个查询会停止评估任何剩余查询,并将值或值分配到指定的凭证类型。数组中的每个查询相互独立。

lookup queries 由单个字段(一个源对象)组成,它可以是多个源类型之一。请参见以下示例:

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  config:
    ...
    services:
    - credentials:
        user_key:
          - <source_type>: <object>
          - <source_type>: <object>
          ...
        app_id:
          - <source_type>: <object>
          ...
        app_key:
          - <source_type>: <object>
          ...
    ...

1.20.6.9. 3scale WebAssembly 模块源对象

source 对象作为任何 credentials 对象字段中的源数组的一部分存在。对象字段名称,称为 source 类型代表以下任意一个:

  • header :查找查询接收 HTTP 请求标头作为输入。
  • query_stringlookup query 接收 URL 查询字符串参数作为输入。
  • filterlookup query 接收过滤器元数据作为输入。

所有 source 类型对象至少具有以下两个字段:

表 1.28. source 类型对象字段

名称描述必需

keys

一个字符串数组,各自对应一个 key,引用输入数据中找到的条目。

ops

用于执行 key 项匹配的操作数组。该数组是操作在下一个操作上接收输入并生成输出的管道。如果 operation 无法提供一个输出将会被解析为 lookup query 失败。操作的管道顺序决定了评估顺序。

选填

filter 字段名称具有所需的 path 条目,用于显示用于查找数据的元数据中的路径。

key 与输入数据匹配时,不会评估其余的密钥,而且源解析算法会跳转到执行指定的操作ops),如果存在。如果没有指定 ops,则返回匹配 key 的结果值(若有)。

Operations 提供了一种方式,用于您在第一阶段查找 key 后为输入指定某些条件和转换。当您需要转换、解码和断言属性时,请使用 Operations,但它们不提供成熟的语言来满足所有需求并缺少 Turing-completeness

存储 operations 输出的堆栈。评估时,lookup query 通过在堆栈的底部分配值或值来完成,具体取决于凭据使用的值。

1.20.6.10. 3scale WebAssembly 模块操作对象

属于特定 source typeops 数组中的每个元素都是 operation 对象,可以应用转换到值或执行测试。用于此类对象的字段名称是 operation 本身的名称,任何值都是 operation 的参数,可以是结构对象,例如,带有字段和值、列表或字符串的映射。

大多数 operation 都参与一个或多个输入,产生一个或多个输出。当它们消耗输入或生成输出时,它们与一个堆栈相关:操作消耗的每个值都从堆栈中弹出,最初填充任何 source 匹配。它们输出的值将推送到堆栈。其他 operations 没有使用或生成的输出不是声明的特定属性,但您检查值的堆栈。

注意

完成解析后,下一步获取的值,例如将值分配给 app_idapp_keyuser_key,取自堆栈的底部值。

有几个不同的 operations 类别:

  • decode :通过解码来转换输入值,使其获得不同的格式。
  • string :这取字符串值作为输入,并对字符串执行转换和检查。
  • stack :它们取输入中的一组值,执行多个堆栈转换,以及堆栈中特定位置的选择。
  • check :这声明了以没有副作用的方式处理一组操作的属性。
  • control :它们执行允许修改评估流的操作。
  • format :它解析输入值的格式特定结构,并在其中查找值。

所有操作都由名称标识符以字符串形式指定。

其他资源

1.20.6.11. 3scale WebAssembly 模块 mapping_rules 对象

mapping_rules 对象是 service 对象的一部分。它指定一组 REST 路径模式和相关 3scale 指标,并在模式匹配时指定要使用的递增数。

如果 system 顶级对象中没有提供动态配置,则需要该值。如果对象在 system 顶级条目外提供,则首先评估 mapping_rules 对象。

mapping_rules 是一个数组对象。该数组的每个元素都是 mapping_rule 对象。传入请求上评估的匹配映射规则提供了一组 3scale methods,用于授权并向 APIManager 报告。当多个匹配规则指代相同的 methods 时,调用 3scale 时会有一个 deltas 的总结。例如,如果两个规则使用 deltas 1 和 3 将 Hits 方法增加两次,则报告至 3scale 的 Hits 的单一方法条目的 delta 为 4。

1.20.6.12. 3scale WebAssembly 模块 mapping_rule 对象

mapping_rule 对象是 mapping_rules 对象中的数组的一部分。

mapping_rule 对象字段指定以下信息:

  • 要匹配的 HTTP 请求方法
  • 匹配路径的模式.
  • 要报告的 3scale 方法以及要报告的数量。指定字段的顺序决定了评估顺序。

表 1.29. mapping_rule 对象字段

名称描述必需

method

指定代表 HTTP 请求方法的字符串,也称为 verb。接受的值与接受的 HTTP 方法名称之一匹配,不区分大小写。任何方法都匹配的特殊值。

pattern

与 HTTP 请求的 URI 路径组件匹配的模式。此模式遵循与 3scale 中记录的相同语法。它允许使用大括号(如 {this})之间的任意字符序列使用通配符(使用星号(*)字符)。

usages

usage 对象列表。当规则匹配时,所有带有其 deltas 的方法都会添加到发送到 3scale 的方法列表中,以进行授权和报告。

使用以下必填字段嵌入 usages 对象 :

  • name: 要报告的 method 系统名。
  • delta: method 增加的数量。

last

当成功与此规则匹配,是否应停止评估更多映射规则。

可选布尔值。默认值为 false

以下示例独立于 3scale 中方法之间的现有层次结构。也就是说,在 3scale 侧运行的任何内容都不会受到影响。例如,Hits 指标可以是全部的父项,因此它存储了 4 个命中,因为授权请求中的所有报告方法总和,并调用 3scale Authrep API 端点。

以下示例使用到匹配所有规则的路径 /products/1/soldGET 请求。

mapping_rules GET 请求示例

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-wasm-auth
spec:
  config:
    ...
    mapping_rules:
      - method: GET
        pattern: /
        usages:
          - name: hits
            delta: 1
      - method: GET
        pattern: /products/
        usages:
          - name: products
            delta: 1
      - method: ANY
        pattern: /products/{id}/sold
        usages:
          - name: sales
            delta: 1
          - name: products
            delta: 1
    ...

所有 usages 都会添加到模块执行的请求中使用用量数据 3scale,如下所示:

  • 命中:1
  • 产品:2 个
  • 销售:1

1.20.7. 凭证用例的 3scale WebAssembly 模块示例

您将花费大部分时间应用配置步骤,在请求您的服务中获取凭证。

以下是 credentials 示例,您可以对其进行修改以符合特定用例的要求。

您可以组合使用它们,尽管当您指定多个源对象和自己的 lookup queries 时,会按照顺序对它们进行评估,直到其中一个成功解析为止。

1.20.7.1. 查询字符串参数中的 API 键 (user_key)

以下示例在查询字符串参数或相同名称的标头中查找 user_key

credentials:
  user_key:
    - query_string:
        keys:
          - user_key
    - header:
        keys:
          - user_key

1.20.7.2. 应用程序 ID 和密钥

以下示例在查询或标头中查找 app_keyapp_id 凭据。

credentials:
  app_id:
    - header:
        keys:
          - app_id
    - query_string:
        keys:
          - app_id
  app_key:
    - header:
        keys:
          - app_key
    - query_string:
        keys:
          - app_key

1.20.7.3. 授权标头

请求在 authorization 标头中包含 app_idapp_key。如果末尾至少输出了一个或两个值,您可以分配 app_key

如果末尾输出了一两个或两个,此处的解决方法将分配 app_key

authorization 标头使用授权类型指定值,其值编码为 Base64。这意味着,您可以通过空格字符来划分值,取第二个输出,然后使用冒号(:)作为分隔符再次分割它。例如,如果您使用这种格式 app_id:app_key,则标头类似以下示例 credential

aladdin:opensesame:  Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

您必须使用小写标头字段名称,如下例所示:

credentials:
  app_id:
    - header:
        keys:
          - authorization
        ops:
          - split:
              separator: " "
              max: 2
          - length:
              min: 2
          - drop:
              head: 1
          - base64_urlsafe
          - split:
              max: 2
  app_key:
    - header:
        keys:
          - app_key

以上用例示例查看 authorization 标头:

  1. 它接受字符串值并通过空格分割,检查它是否至少生成两个 credential 类型和 credential 本身,然后丢弃 credential 类型。
  2. 然后,它会解码包含所需数据的第二个值,并使用冒号(:)字符进行拆分,使其具有一个包含 app_id 的操作堆栈,然后解码 app_key (若存在)。

    1. 如果授权标头中不存在 app_key,则将检查其特定源,例如本例中带有键 app_key 的标头。
  3. 要向 credentials 添加额外条件,允许 Basic 授权,其中 app_idaladdinadmin,或者任何 app_id 长度至少为 8 个字符。
  4. app_key 必须包含一个值,并且至少具有 64 个字符,如下例所示:

    credentials:
      app_id:
        - header:
            keys:
              - authorization
            ops:
              - split:
                  separator: " "
                  max: 2
              - length:
                  min: 2
              - reverse
              - glob:
                - Basic
              - drop:
                  tail: 1
              - base64_urlsafe
              - split:
                  max: 2
              - test:
                  if:
                    length:
                      min: 2
                  then:
                    - strlen:
                        max: 63
                    - or:
                        - strlen:
                            min: 1
                        - drop:
                            tail: 1
              - assert:
                - and:
                  - reverse
                  - or:
                    - strlen:
                        min: 8
                    - glob:
                      - aladdin
                      - admin
  5. 选取 authorization 标头值后,您可以通过淘汰堆栈来获取 Basic credential 类型,使类型放置在顶部。
  6. 在其上运行通配匹配。验证凭据并且凭据被解码和分割后,您将获得堆栈底部的 app_id,还可能获得顶部的 app_key
  7. 运行 测试: 如果堆栈中有两个值,表示已获取 app_key

    1. 确保字符串长度介于 1 到 63 之间,包括 app_idapp_key。如果密钥的长度为零,则将其丢弃,并像不存在密钥一样继续。如果只有一个 app_id 且没有 app_key,则缺少的其他分支表示测试和评估成功。

assert,最后一个操作表示它使它进入堆栈没有副作用。然后您可以修改堆栈:

  1. 颠倒堆栈,使 app_id 位于顶部。

    1. 无论是否存在 app_key,取代堆栈可确保 app_id 处于顶级。
  2. 使用 and 在测试期间保留堆栈的内容。

    然后使用以下可能性之一:

    • 确保 app_id 的字符串长度至少为 8。
    • 确保 app_idaladdinadmin 匹配。

1.20.7.4. OpenID Connect(OIDC)用例

对于 Service Mesh 和 3scale Istio 适配器,您必须部署一个 RequestAuthentication,如下例所示,填入您自己的工作负载数据和 jwtRules:

apiVersion: security.istio.io/v1beta1
  kind: RequestAuthentication
  metadata:
    name: jwt-example
    namespace: bookinfo
  spec:
    selector:
      matchLabels:
        app: productpage
    jwtRules:
    - issuer: >-
        http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak
      jwksUri: >-
        http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak/protocol/openid-connect/certs

应用 RequestAuthentication 时,它会使用原生插件配置 Envoy 以验证 JWT 令牌。代理会在运行模块前验证所有内容,因此任何失败的请求都不会将其发送到 3scale WebAssembly 模块。

验证 JWT 令牌时,代理将其内容存储在内部元数据对象中,其键取决于插件的具体配置。通过这个用例,您可以通过包含未知密钥名称的单一条目来查找结构对象。

OIDC 的 3scale app_id 与 OAuth client_id 匹配。这可在 JWT 令牌的 azpaud 字段中找到。

要从 Envoy 的原生 JWT 身份验证过滤器获取 app_id 字段,请参阅以下示例:

credentials:
  app_id:
    - filter:
        path:
          - envoy.filters.http.jwt_authn
          - "0"
        keys:
          - azp
          - aud
        ops:
          - take:
              head: 1

示例指示模块使用 filter 源类型从 Envoy特定的 JWT 身份验证原生插件中查找对象的过滤器元数据。此插件包含 JWT 令牌,作为具有单个条目和预配置名称的结构对象的一部分。使用 0 指定您将仅访问单个条目。

生成值是一个结构,您要解析以下两个字段:

  • azp :找到 app_id 的值。
  • aud: 也可以找到这个信息的值。

该操作可确保仅保留一个值进行分配。

1.20.7.5. 从标头中选取 JWT 令牌

一些设置可能具有 JWT 令牌的验证流程,验证令牌可通过 JSON 格式的标头访问此模块。

要获得 app_id,请参阅以下示例:

credentials:
  app_id:
    - header:
        keys:
          - x-jwt-payload
        ops:
          - base64_urlsafe
          - json:
            - keys:
              - azp
              - aud
          - take:
              head: 1

1.20.8. 3scale WebAssembly 模块最小工作配置

以下是 3scale WebAssembly 模块最小工作配置的示例:您可以复制并粘贴此内容,并编辑它以便使用自己的配置。

apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
  name: threescale-auth
spec:
  image: registry.redhat.io/openshift-service-mesh/3scale-auth-wasm-rhel8:0.0.1
  phase: PostAuthZ
  priority: 100
  workloadSelector:
    labels:
      app: productpage
  config:
    api: v1
    system:
      name: system-name
      upstream:
        name: outbound|443||multitenant.3scale.net
        url: https://istiodevel-admin.3scale.net/
        timeout: 5000
      token: atoken
    backend:
      name: backend-name
      upstream:
        name: outbound|443||su1.3scale.net
        url: https://su1.3scale.net/
        timeout: 5000
      extensions:
      - no_body
    services:
    - id: '2555417834780'
      token: service_token
      authorities:
      - "*"
        credentials:
          app_id:
            - header:
                keys:
                  - app_id
            - query_string:
                keys:
                  - app_id
                  - application_id
          app_key:
            - header:
                keys:
                  - app_key
            - query_string:
                keys:
                  - app_key
                  - application_key
          user_key:
            - query_string:
                keys:
                  - user_key
            - header:
                keys:
                  - user_key
      mapping_rules:
      - method: GET
        pattern: "/"
        usages:
        - name: Hits
          delta: 1
      - method: GET
        pattern: "/o{*}c"
        usages:
        - name: oidc
          delta: 1
        - name: Hits
          delta: 1
      - method: any
        pattern: "/{anything}?bigsale={*}"
        usages:
        - name: sale
          delta: 5