本文以入口网关访问productpage应用为例,介绍如何在ASM网关上使用自定义授权服务。
前提条件
背景信息
客户端发起业务请求,后端需要验证用户请求的合法性。例如,判断用户请求是否有该资源访问权限。认证通过后,返回结果中还需要增加一些原始请求中没有的信息,例如用户认证通过后在header中添加业务版本号、用户ID等。
针对上述业务场景,ASM提供了自定义授权服务。在ASM网关上加入鉴权流程,以确保只有得到授权的情况下,才能访问关键服务。
自定义授权服务属于服务网格的高级安全能力。如果您的需求较为简单,可以参考网关黑白名单或授权策略进行配置;如果您的需求较为复杂,可以参照本文进行配置。
配置说明
自定义授权服务是需要您自行开发的一个授权服务。本文以部署一个已实现的简易授权服务为例,将到达网关的指定请求导向自定义授权服务,由该授权服务决定是否允许该请求通过,然后网关会根据授权结果决定放行或拒绝该请求。
您需要配置以下两部分信息:
网关和自定义授权服务互相对接的信息。
指定该网关的哪些请求需要由自定义授权服务进行鉴权。
步骤一:部署自定义授权服务
在ACK集群中部署自定义授权服务,该服务需遵循Istio自定义鉴权服务接口规范,支持HTTP和gRPC协议,用于实现自定义鉴权逻辑。本文使用的示例服务要求请求必须带有x-ext-authz: allow
请求头,才能通过鉴权访问成功。
本文提供了自定义授权服务示例,您可以参考本示例应用的代码,创建自己的自定义授权服务。具体操作,请参见自定义授权。
通过kubectl管理集群和应用。具体操作,请参见通过kubectl工具连接集群。
使用以下内容,创建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 ---
执行以下命令,在集群中部署自定义授权服务。
kubectl apply -f ext-authz.yaml
执行以下命令,查看Pod状态。
kubectl get pod
预期输出:
NAME READY STATUS RESTARTS AGE ext-authz-6d458d5f8f-bh2m9 2/2 Running 0 1m
执行以下命令,验证应用是否正常工作。
kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz
预期输出:
2022/08/07 22:55:47 Starting HTTP server at [::]:8000 2022/08/07 22:55:47 Starting gRPC server at [::]:9000
返回以上结果,说明应用正常工作,自定义授权服务部署成功。
获取ext-authz授权服务的gRPC和HTTP协议端口。
- 登录容器服务管理控制台,在左侧导航栏选择集群。
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在服务页面,单击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控制台进行配置。
- 登录ASM控制台,在左侧导航栏,选择 。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在入口网关页面,单击目标网关名称。
在网关概览页面左侧,单击 。
在自定义授权服务配置配置向导,打开启用网关自定义授权服务开关,任选以下方式,配置自定义授权服务,然后单击下一步。
方式一:未创建自定义授权服务
在基于envoy.ext_authz实现的自定义授权服务(HTTP或gRPC协议)页签,进行如下配置。关于配置项的说明,请参见接入HTTP协议的自定义授权服务。
方式二:已创建自定义授权服务
在导入已有自定义授权服务页签,选择已有自定义授权服务。
在匹配规则配置向导,进行相关配置,然后单击提交。
被该规则匹配到的请求,将会执行自定义授权。
配置完成后,页面会显示ASM安全策略创建成功。
步骤三:验证ASM网关使用自定义授权服务是否成功
执行以下命令,访问
http://{您的ASM网关地址}/api/v1/products
。curl -I http://{您的ASM网关地址}/api/v1/products
预期输出:
HTTP/1.1 200 OK content-type: application/json content-length: 395 server: istio-envoy date: Fri, 23 Dec 2022 02:58:47 GMT x-envoy-upstream-service-time: 2
返回以上结果,说明没有触发鉴权。访问的路径为
/api/v1/products
,不是上文配置的/productpage
,所以不被授权策略约束。执行以下命令,带有
x-ext-authz: deny
请求头访问http://{您的ASM网关地址}/productpage
。curl -I -H "x-ext-authz: deny" http://{您的ASM网关地址}/productpage
预期输出:
HTTP/1.1 403 Forbidden x-ext-authz-check-result: denied content-length: 76 content-type: text/plain; charset=utf-8 date: Fri, 23 Dec 2022 03:00:43 GMT server: istio-envoy denied by ext_authz for not found header `x-ext-authz: allow` in the request%
返回以上结果,说明触发鉴权,但是鉴权未通过。返回的结果中包含新定义的响应头
x-ext-authz-check-result: denied
。访问的路径是授权策略中定义的/productpage
,所以会被授权策略约束。执行以下命令,带有
x-ext-authz: allow
请求头访问http://{您的ASM网关地址}/productpage
。curl -I -H "x-ext-authz: allow" http://{您的ASM网关地址}/productpage
预期输出:
TP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 4294 server: istio-envoy date: Fri, 23 Dec 2022 03:02:28 GMT x-envoy-upstream-service-time: 17
返回以上结果,说明触发鉴权,并且鉴权通过。返回的结果中包含新定义的响应头
x-ext-authz-check-result: allowed
。 鉴权通过后,网关转发给应用的请求中会携带x-ext-authz-check-result的header(值为allowed
)。携带这个header是因为本文自定义授权服务会添加该header,且上文配置中允许授权响应携带该header。
自定义授权服务实现流程
ASM对于Istio自定义授权进行了封装。如果您想了解Istio原生的实现流程,可以查看ASM为您生成的原生Istio资源。实现方案示例如下:
