在服务网格中配置JWT(JSON Web Token)请求授权,可以实现来源认证,又称为最终用户认证。在接收用户请求时,该配置用于认证请求头信息中的Access Token是否可信,并授权给来源合法的请求。本文介绍如何在ASM中对入口网关进行JWT请求鉴权,使之通过入口网关访问服务时,必须带有可信的Access Token。
前提条件
- 已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。 
- 已部署入口网关。具体操作,请参见创建入口网关。 
背景信息
本文以httpbin服务为例,使用请求身份认证对通过入口网关访问服务的请求进行限制,实现只有带有正确的JWT Token才能访问服务成功,错误的JWT Token将访问服务失败,但是不带有JWT Token也能访问服务成功。在此基础上,您可以使用授权策略对请求进行进一步限制,分为两个场景:
- 使用授权策略,使之请求必须带有JWT Token,才能通过入口网关访问服务成功。 
- 使用授权策略,使之请求必须带有固定颁发者的JWT Token,才能通过入口网关访问服务成功。 
步骤一:部署示例服务
- 为default命名空间开启自动注入。 - 登录ASM控制台。 
- 在左侧导航栏,选择。 
- 在网格详情页面左侧导航栏,选择。 
- 在全局命名空间页面,单击default右侧自动注入列下的启用 Sidecar 网格代理自动注入。 
- 在确认对话框单击确定。 
 
- 部署示例服务。 - 使用以下内容,创建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 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颁发者进行限制成功。 
 
