在服务网格中配置JWT(JSON Web Token)请求授权,可以实现来源认证,又称为最终用户认证。在接收用户请求时,该配置用于认证请求头信息中的Access Token是否可信,并授权给来源合法的请求。本文介绍如何在ASM中对入口网关进行JWT请求鉴权,使之通过入口网关访问服务时,必须带有可信的Access Token。
背景信息
本文以httpbin服务为例,使用请求身份认证对通过入口网关访问服务的请求进行限制,实现只有带有正确的JWT Token才能访问服务成功,错误的JWT Token将访问服务失败,但是不带有JWT Token也能访问服务成功。在此基础上,您可以使用授权策略对请求进行进一步限制,分为两个场景:- 使用授权策略,使之请求必须带有JWT Token,才能通过入口网关访问服务成功。
- 使用授权策略,使之请求必须带有固定颁发者的JWT Token,才能通过入口网关访问服务成功。
步骤一:部署示例服务
- 为default命名空间开启自动注入。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格详情页面左侧导航栏,选择。
- 在全局命名空间页面单击default右侧自动注入列下的启用Sidecar自动注入。
- 在确认对话框单击确定。
- 部署示例服务。
- 获取集群KubeConfig并通过kubectl工具连接集群。
- 使用以下内容,创建httpbin.yaml。
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
- 执行以下命令,创建httpbin应用。
kubectl apply -f httpbin.yaml -n default
步骤二:创建网关规则和虚拟服务
- 创建网关规则。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏,选择,然后在右侧页面,单击使用YAML创建。
- 设置命名空间为default,输入以下内容到文本框,然后单击创建。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: httpbin-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
- 创建虚拟服务。
- 在网格详情页面左侧导航栏,选择,然后在右侧页面,单击使用YAML创建。
- 设置命名空间为default,输入以下内容到文本框,然后单击创建。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: default
spec:
gateways:
- httpbin-gateway
hosts:
- '*'
http:
- route:
- destination:
host: httpbin
port:
number: 8000
步骤三:创建请求身份认证
- 创建JWK。
- 在openssl中执行以下命令,生成2048位的RSA私钥。
openssl genrsa -out rsa-private-key.pem 2048
- 执行以下命令,通过私钥生成公钥。
openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
- 在JWK to PEM Convertor online工具中选中PEM-to-JWK (RSA Only),输入公钥,单击submit,将公钥转化为JWK。
{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add7863915c","n":"2dnwOlDKEwII9Cyh9w7o59a5y3RS2gWUKYC3HSBJL1FhYIZa7sjTCKxwEuG-vCRQkR6augWxYWseSDfgtyivzi3CxxkF8WnQbECOCGm5xAYKmMcXeOpv0zsJTHN122Tt_tsd6K2OC3yGwKtmp7m-MOpHagqWRqFtvyEOm_1JW1-t0n1VsGSeWww8dvcmnJPKAKHbAU40jdV1hMn9AA3RfSpDY6nfrUkpXA5-aQ6rJRjMn36DatZ5ykVL4LKPOUxZdfK_yNIPkCnwIKesqiOpr4s-iCM8pMiZuejDZ1qoX-uBjggESf4G9_L-laDSeoDmXeOZ9kzN3Jw8ay69ihIFEQ"}
- 创建请求身份认证。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏选择,然后在右侧页面单击创建。
- 在创建页面配置相关信息,然后单击创建。

配置项 | 描述 |
---|
命名空间 | 设置命名空间为istio-system。 |
名称 | 输入名称。 |
匹配标签 | 匹配标签用于匹配请求身份认证生效的服务。 单击新增匹配标签,设置名称为istio,值为ingressgateway。 |
jwt规则集 | 单击jwt规则集右侧的添加,设置JWT规则:- issuer:JWT的颁发者,本文设置为testing@asm.test.io。
- audiences:JWT受众列表。设置哪些服务可以使用JWT Token访问目标服务。本文设置为空,表示对访问的服务不受限制。
- jwks:设置JWT信息,本文设置为
{"keys":[步骤1创建的JWK]} ,例如步骤1创建的JWK为{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"} ,则jwks为{"keys":[{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}]} 。
|
步骤四:验证请求身份认证是否生效
- 使用JWT工具将JWT请求信息编码成JWT Token。
在
Decoded区域输入以下JWT请求信息,在
Encode区域将自动转换成JWT Token。
- HEADRE:设置加密算法为RS256,输入JWK中的kid,设置类型为JWT。
- PAYLOAD:设置iss为testing@asm.test.io,您还可以添加自定义的额外信息。
- VERIFY SIGNATURE:输入步骤1的创建的公钥和私钥。

- 通过入口网关访问服务。
- 执行以下命令,带有步骤1创建的JWT Token的请求访问服务。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 18 Mar 2022 07:27:54 GMT
- 执行以下命令,带有无效的JWT Token的请求访问服务。
curl -I -H "Authorization: Bearer invalidToken" http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 401 Unauthorized
www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
content-length: 79
content-type: text/plain
date: Fri, 18 Mar 2022 07:59:00 GMT
server: istio-envoy
- 执行以下命令,不带有JWT Token的请求访问服务。
curl -I http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 18 Mar 2022 07:27:54 GMT
根据以上结果,可以看到带有正确的JWT Token或不带有JWT Token的请求访问服务成功,带有错误的JWT Token的请求访问服务失败,说明请求身份认证生效。
步骤五:创建授权策略
场景一:使用授权策略对访问服务的请求进行限制
创建授权策略,使之请求必须带有JWT Token,才能通过入口网关访问服务。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏,选择,然后在右侧页面,单击创建。
- 在创建页面配置相关信息,然后单击创建。

配置项 | 说明 |
---|
名称 | 输入授权策略的名称。 |
策略类型 | 设置策略类型为允许。 |
网关生效 | 单击网关生效页签,设置ASM网关为ingressgateway。在添加请求来源区域,打开请求JWT主体(RequestPrincipals)开关,在对应文本框中输入*。 |
- 验证使用授权策略对访问服务的请求进行限制是否成功。
- 执行以下命令,不带有JWT Token的请求访问服务。
curl -I http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 401 Unauthorized
www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
content-length: 79
content-type: text/plain
date: Fri, 18 Mar 2022 07:59:00 GMT
server: istio-envoy
- 执行以下命令,使用带有JWT Token的请求访问服务。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 18 Mar 2022 07:27:54 GMT
可以看到不带有JWT Token的请求访问服务失败,带有JWT Token的请求访问服务成功,说明使用授权策略对访问服务的请求进行限制成功。
场景二:使用授权策略对访问服务的请求的JWT Token颁发者进行限制
创建授权策略,使之请求必须带有颁发者为testing@asm.test.io的JWT Token,才能通过入口网关访问服务。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏,选择,然后在右侧页面,单击创建。
- 在创建页面配置相关信息,然后单击创建。

配置项 | 说明 |
---|
名称 | 输入授权策略的名称。 |
策略类型 | 设置策略类型为允许。 |
网关生效 | 单击网关生效页签,设置ASM网关为ingressgateway。在添加请求来源区域,打开请求JWT主体(RequestPrincipals)开关,在对应文本框中输入testing@asm.test.io/demo@asm.test.io。 |
- 验证使用授权策略对访问服务的请求的颁发者进行限制是否成功。
- 执行以下命令,使用带有JWT Token的请求访问服务。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 401 Unauthorized
www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
content-length: 79
content-type: text/plain
date: Fri, 18 Mar 2022 07:59:00 GMT
server: istio-envoy
授权策略限制了访问服务的请求的JWT Token的颁发者必须为testing@asm.test.io/demo@asm.test.io,所以带有颁发者为testing@asm.test.io的JWT Token请求访问失败。
- 修改JWT Token的颁发者为testing@asm.test.io/demo@asm.test.io。
在
JWT工具中
PAYLOAD中设置
iss为testing@asm.test.io,sub为demo@asm.test.io。其他配置和步骤
1保持相同。

- 执行以下命令,使用上文生成JWT Token的请求访问服务。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM网关地址}/
预期输出:
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 18 Mar 2022 07:27:54 GMT
带有颁发者为testing@asm.test.io/demo@asm.test.io的JWT Token请求访问服务成功,说明使用授权策略对访问服务的请求的JWT Token颁发者进行限制成功。