In Service Mesh (ASM), you can configure JSON Web Token (JWT) authentication to authenticate the source of requests. This method is also called end-user authentication. After you configure JWT authentication for an ingress gateway on an ASM instance, ASM checks whether the requests to access services by using the ingress gateway contain a valid JWT in the request headers. Only requests that contain a valid JWT are allowed. This topic describes how to configure JWT authentication for an ingress gateway.
Prerequisites
- The cluster is added to the ASM instance. For more information, see Add a cluster to an ASM instance.
- An ingress gateway service is deployed. For more information, see Create an ingress gateway.
Background information
In this example, the httpbin service is used. A request authentication policy is configured for an ingress gateway to restrict the requests that attempt to access the httpbin service. Requests that contain a valid JWT are allowed to access the httpbin service. Requests that contain an invalid JWT are rejected. However, requests that contain no JWT are also allowed to access the httpbin service. Based on this request authentication policy, you can create authorization policies to further restrict requests in the following scenarios:
Create an authorization policy to allow only requests that contain a valid JWT to access the service by using the ingress gateway.
Create an authorization policy to allow only requests that contain a JWT issued by the specified issuer to access the service by using the ingress gateway.
Step 1: Deploy the httpbin service
Enable automatic sidecar proxy injection for the default namespace.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the details page of the ASM instance, choose in the left-side navigation pane.
On the Global Namespace page, find the default namespace and click Enable Automatic Sidecar Proxy Injection in the Automatic Sidecar Injection column.
In the Submit message, click OK.
Deploy the httpbin service.
Connect to a Container Service for Kubernetes (ACK) cluster by using kubectl. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
Create an httpbin.yaml file that contains the following content:
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
Run the following command to deploy the httpbin service:
kubectl apply -f httpbin.yaml -n default
Step 2: Create an Istio gateway and a virtual service
Create an Istio gateway.
- Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose
. On the page that appears, click Create from YAML.On the Create page, select default from the Namespace drop-down list and copy the following content to the code editor. Then, click Create.
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
Create a virtual service.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
On the Create page, select default from the Namespace drop-down list and copy the following content to the code editor. Then, click Create.
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
Step 3: Create a request authentication policy
Create a JSON Web Key (JWK).
Run the following command in OpenSSL to generate a 2048-bit Rivest-Shamir-Adleman (RSA) private key:
openssl genrsa -out rsa-private-key.pem 2048
Run the following command to extract the public key from the private key file:
openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
In the JWK to PEM Convertor online tool, select PEM-to-JWK (RSA Only), enter the public key in the code editor, and then click submit to convert the public key to a JWK.
{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add7863915c","n":"2dnwOlDKEwII9Cyh9w7o59a5y3RS2gWUKYC3HSBJL1FhYIZa7sjTCKxwEuG-vCRQkR6augWxYWseSDfgtyivzi3CxxkF8WnQbECOCGm5xAYKmMcXeOpv0zsJTHN122Tt_tsd6K2OC3yGwKtmp7m-MOpHagqWRqFtvyEOm_1JW1-t0n1VsGSeWww8dvcmnJPKAKHbAU40jdV1hMn9AA3RfSpDY6nfrUkpXA5-aQ6rJRjMn36DatZ5ykVL4LKPOUxZdfK_yNIPkCnwIKesqiOpr4s-iCM8pMiZuejDZ1qoX-uBjggESf4G9_L-laDSeoDmXeOZ9kzN3Jw8ay69ihIFEQ"}
Create a request authentication policy.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create.
On the Create page, set the parameters and click Create.
Parameter
Description
Namespace
The namespace in which you create the request authentication policy. In this example, istio-system is selected from the drop-down list.
Name
The name of the request authentication policy.
Matching Label
The label that is used to specify the service to which the request authentication policy applies.
Click Add Matching Label. Set the Name parameter to istio and the Value parameter to ingressgateway.
JWT Rule Set
The JWT rules. Click Add next to JWT Rule Set and set the following parameters:
issuer: the issuer of the JWT. In this example, the value is set to testing@asm.test.io.
audiences: the audiences of the JWT. This parameter specifies the services that can use the JWT to access the desired service. If you do not set this parameter, all services can access the desired service.
jwks: the information about the JWT, in the
{"keys":[JWK created in Step 1]}
format. For example, if the JWK that you created in Step 1 is{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}
, set this parameter to{"keys":[{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}]}
.
Step 4: Check whether the request authentication policy takes effect
Use the JWT tool to encode JWT request information into a JWT string.
In the Decoded section, enter the following JWT request information. Then, the JWT request information is automatically converted to a JWT in the Encoded section.
HEADER: Set the alg parameter to RS256, the kid parameter to the key ID of the JWK that you created, and the typ parameter to JWT.
PAYLOAD: Set the iss parameter to testing@asm.test.io. You can add additional information based on your business requirements.
VERIFY SIGNATURE: Enter the public key and private key created in the first substep of Step 3: Create a request authentication policy.
Access the httpbin service by using the ingress gateway.
Run the following command to send a request to access the httpbin service. The request contains the JWT created in Substep 1.
curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of the ingress gateway}/
Expected output:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
Run the following command to send a request that contains an invalid JWT to access the httpbin service:
curl -I -H "Authorization: Bearer invalidToken" http://{IP address of the ingress gateway}/
Expected output:
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
Run the following command to send a request that contains no JWT to access the httpbin service:
curl -I http://{IP address of the ingress gateway}/
Expected output:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
The preceding results indicate that a request to access the httpbin service is allowed if the request contains a valid JWT or does not contain a JWT, and a request that contains an invalid JWT is not allowed. This indicates that the request authentication policy takes effect.
Step 5: Create an authorization policy
Scenario 1: Create an authorization policy to allow only requests that contain a valid JWT to access the service by using the ingress gateway
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create.
On the Create page, set the parameters and click Create.
Parameter
Description
Name
The name of the authorization policy.
Policy Type
The authorization action. In this example, the value is set to ALLOW.
Gateway Scope
The gateway for which the authorization policy takes effect. In this example, the ASM Gateway parameter on the Gateway Scope tab is set to ingressgateway. In the Add Request Source section, turn on RequestPrincipals and enter * in the field.
Check whether the authorization policy takes effect.
Run the following command to send a request that contains no JWT to access the httpbin service:
curl -I http://{IP address of the ingress gateway}/
Expected output:
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
Run the following command to send a request that contains a valid JWT to access the httpbin service:
curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of the ingress gateway}/
Expected output:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
The preceding results indicate that a request to access the httpbin service is allowed if the request contains a valid JWT, and a request that contains no JWT is not allowed. This indicates that the authorization policy takes effect.
Scenario 2: Create an authorization policy to allow only requests that contain a JWT issued by the specified issuer to access the service by using the ingress gateway
In this example, the issuer is testing@asm.test.io.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create.
On the Create page, set the parameters and click Create.
Parameter
Description
Name
The name of the authorization policy.
Policy Type
The authorization action. In this example, the value is set to ALLOW.
Gateway Scope
The gateway for which the authorization policy takes effect. In this example, the ASM Gateway parameter on the Gateway Scope tab is set to ingressgateway. In the Add Request Source section, RequestPrincipals is turned on and the value is set to testing@asm.test.io/demo@asm.test.io.
Check whether the authorization policy takes effect.
Run the following command to send a request that contains a JWT issued by testing@asm.test.io to access the httpbin service:
curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of the ingress gateway}/
Expected output:
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
The authorization policy specifies testing@asm.test.io/demo@asm.test.io as the allowed JWT issuer. Therefore, requests that contain a JWT issued by testing@asm.test.io are not allowed to access the httpbin service.
Change the issuer of the JWT to testing@asm.test.io/demo@asm.test.io.
Run the following command to send a request that contains the JWT generated in the preceding substep to access the httpbin service:
curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of the ingress gateway}/
Expected output:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
The request that contains the JWT issued by testing@asm.test.io/demo@asm.test.io is allowed to access the httpbin service. This indicates that the authorization policy takes effect.