在ASM网关上使用自定义授权服务

当您需要按照自身需求定制访问控制策略时,例如基于HTTP域名、HTTP路径、HTTP方法等对请求进行鉴权,可以在ASM网关上使用自定义授权服务,确保只有经过认证的用户才能访问关键服务。

前提条件

功能介绍

客户端发起业务请求,后端需要验证用户请求的合法性。例如,判断用户请求是否有该资源访问权限。认证通过后,返回结果中还需要增加一些原始请求中没有的信息,例如用户认证通过后在header中添加业务版本号、用户ID等。ASM提供了自定义授权服务。在ASM网关上加入鉴权流程,以确保只有得到授权的情况下,才能访问关键服务。

自定义授权服务是需要您自行开发的一个授权服务。本文以部署一个已实现的简易授权服务为例,将到达网关的指定请求导向自定义授权服务,由该授权服务决定是否允许该请求通过,然后网关会根据授权结果决定放行或拒绝该请求。您需要配置以下两部分信息:

  • 网关和自定义授权服务互相对接的信息。

  • 指定该网关的哪些请求需要由自定义授权服务进行鉴权。

自定义授权服务属于服务网格的高级安全能力。如果您的需求较为简单,可以参考网关黑白名单授权策略进行配置;如果您的需求较为复杂,可以参照本文进行配置。

实现流程

ASM对于Istio自定义授权进行了封装。如果您想了解Istio原生的实现流程,可以查看ASM为您生成的原生Istio资源。ASM自定义授权服务实现流程示例如下:

  1. 在ASM定义自定义授权服务,关联步骤一创建的自定义授权服务,使ASM可以使用该服务进行鉴权。

  2. 在ASM创建授权策略,配置需要自定义鉴权的应用,并将鉴权指向步骤二配置的自定义授权服务。

基于ASM实现应用请求认证授权

步骤一:部署自定义授权服务

在ACK集群中部署自定义授权服务,该服务需遵循Istio自定义鉴权服务接口规范,支持HTTP和gRPC协议,用于实现自定义鉴权逻辑。本文使用的示例服务要求请求必须带有x-ext-authz: allow请求头,才能通过鉴权访问成功。

说明

本文提供了自定义授权服务示例,您可以参考本示例应用的代码,创建自己的自定义授权服务。具体操作,请参见自定义授权

  1. 使用以下内容,创建ext-authz.yaml

    展开查看ext-authz.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    # Example configurations for deploying ext-authz server separately in the mesh.
    
    apiVersion: v1
    kind: Service
    metadata:
      name: ext-authz
      labels:
        app: ext-authz
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 8000
      - name: grpc
        port: 9000
        targetPort: 9000
      selector:
        app: ext-authz
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ext-authz
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ext-authz
      template:
        metadata:
          labels:
            app: ext-authz
        spec:
          containers:
          - image: istio/ext-authz:0.6
            imagePullPolicy: IfNotPresent
            name: ext-authz
            ports:
            - containerPort: 8000
            - containerPort: 9000
    ---
  2. 执行以下命令,在集群中部署自定义授权服务。

    关于如何通过kubectl管理集群和应用,请参见通过kubectl工具连接集群

    kubectl apply -f ext-authz.yaml
  3. 执行以下命令,查看Pod状态。

    kubectl get pod

    预期输出:

    NAME                              READY   STATUS    RESTARTS       AGE
    ext-authz-6d458d5f8f-bh2m9        2/2     Running   0              1m
  4. 执行以下命令,验证应用是否正常工作。

    kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz

    预期输出:

    2023/12/12 10:01:31 Starting HTTP server at [::]:8000
    2023/12/12 10:01:31 Starting gRPC server at [::]:9000

    返回以上结果,说明应用正常工作,自定义授权服务部署成功。

  5. 获取ext-authz授权服务的gRPC和HTTP协议端口。

    1. 登录容器服务管理控制台,在左侧导航栏选择集群

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择网络 > 服务

    3. 服务页面,单击ext-authz

      端点区域可以看到gRPC协议的端口为9000,HTTP协议的端口为8000。因此访问该服务的gRPC地址为ext-authz.default.svc.cluster.local:9000,HTTP地址为ext-authz.default.svc.cluster.local:8000

步骤二:在网关配置HTTP协议的自定义授权服务

ASM网关集成了自定义授权的能力,支持通过ASM控制台进行配置。

  1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

  2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择ASM网关 > 入口网关

  3. 入口网关页面,单击目标网关名称。

  4. 在网关概览导航栏,单击网关安全 > 自定义授权服务

  5. 自定义授权服务配置配置向导,打开启用网关自定义授权服务开关,任选以下方式,配置自定义授权服务,然后单击下一步

    方式一:新建自定义授权服务

    基于envoy.ext_authz实现的自定义授权服务(HTTP或gRPC协议)页签,进行如下配置。关于配置项的说明,请参见接入HTTP协议的自定义授权服务基于envoy.ext_authz实现的自定义授权服务(HTTP或gRPC协议)headerheader配置

    方式二:导入已有的自定义授权服务

    导入已有自定义授权服务页签,选择已有自定义授权服务

  6. 匹配规则配置向导,进行如下配置,然后单击提交

    被该规则匹配到的请求,将会执行自定义授权。匹配规则

    配置完成后,页面会显示网关自定义授权服务创建成功

步骤三:验证ASM网关使用自定义授权服务是否成功

  1. 执行以下命令,访问网关上/api/v1/products路径的资源。

    关于如何获取网关地址,请参见获取入口网关地址

    curl -I http://{您的ASM网关地址}/api/v1/products

    预期输出:

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Wed, 13 Dec 2023 02:41:20 GMT
    content-type: application/json
    content-length: 395
    x-envoy-upstream-service-time: 1

    返回以上结果,说明没有触发鉴权。访问的路径为/api/v1/products,不是上文配置的/productpage,所以不被授权策略约束。

  2. 执行以下命令,带有x-ext-authz: deny请求头访问/productpage路径的资源。

    curl -I -H "x-ext-authz: deny" http://{您的ASM网关地址}/productpage

    预期输出:

    HTTP/1.1 403 Forbidden
    x-ext-authz-check-result: denied
    date: Wed, 13 Dec 2023 02:42:59 GMT
    server: istio-envoy
    transfer-encoding: chunked

    返回以上结果,说明触发鉴权,但是鉴权未通过。返回的结果中包含新定义的响应头x-ext-authz-check-result: denied。访问的路径是授权策略中定义的/productpage,所以会被授权策略约束。

  3. 执行以下命令,带有x-ext-authz: allow请求头访问/productpage路径的资源。

    curl -I -H "x-ext-authz: allow" http://{您的ASM网关地址}/productpage

    预期输出:

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Wed, 13 Dec 2023 02:50:38 GMT
    content-type: text/html; charset=utf-8
    content-length: 5290
    x-envoy-upstream-service-time: 47

    返回以上结果,说明触发鉴权,并且鉴权通过。鉴权通过后,网关转发给应用的请求中会携带x-ext-authz-check-result的header(值为allowed)。携带这个header是因为本文自定义授权服务会添加该header,且上文配置中允许授权响应携带该header。

相关文档

  • ASM网关支持从源地址、HTTP域名、端口、远程源IP四个维度配置黑白名单,以保障网格内应用的安全。具体操作,请参见在ASM网关中配置黑白名单

  • 您可以借助阿里云IDaaS或其他符合OIDC标准的身份提供者,无需修改应用本身,即可实现一次登录、多次访问。具体操作,请参见在ASM网关中配置OIDC单点登录