This topic provides answers to frequently asked questions about JSON Web Token (JWT) authentication in Alibaba Cloud Service Mesh (ASM), including JWT algorithm support, JwksUri configuration for services inside and outside a cluster, and path-level authentication exclusion.
Prerequisites
An ASM instance is created.
For JwksUri-related configurations, ASM 1.13 or later is required.
A kubeconfig for the data plane cluster is configured to run
kubectlcommands.
What JWT algorithms does ASM support?
ASM versions earlier than 1.13 support only the RSA algorithm.
ASM 1.13 and later support the following JWT algorithms: ES256, ES384, ES512, HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, and EdDSA.
How do I use a JwksUri in ASM?
You must use Alibaba Cloud Service Mesh 1.13 or later. There are two ways to use a JwksUri:
If the JwksUri points to a service inside the cluster, you can configure it directly.
If the JwksUri points to a service outside the cluster, you must configure a corresponding ServiceEntry.
This topic uses the official Istio JWT and Jwks samples as an example. For more information, see JWT and Jwks.
Use a JwksUri address inside the cluster
This topic assumes that the JwksUri address is an address in a cluster managed by Service Mesh. nginx-proxy is a service in the cluster. Its /get_jwks endpoint on port 80 returns the jwks public key information, and the JwksUri is http://nginx-proxy.{Namespace}.svc.cluster.local:80/get_jwks.
Run the following command to check whether the get_jwks endpoint of the cluster is available.
curl nginx-proxy/get_jwksExpected output:
{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-e****","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65p****-P7KfIupjf59vsdo91bSP9C8H07pSAGQ****_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5****_pbhLdKXbi66GlVeK6ABZOUW3WYt****-91gVuoeJT_DwtGGcp4ignkgXfkiE****-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoU****_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZ****_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqT****_EyxOGuHJrLsn00****"}]}A
200response with key data indicates that the get_jwks endpoint is available.Create a request authentication.
-
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.
In the left-side navigation pane, click Mesh Security CenterRequestAuthentication.
On the RequestAuthentication page, click Create from YAML, select the target Namespaces and any Scenario Template, configure the following YAML, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: foo spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: 'http://nginx-proxy/get_jwks' selector: matchLabels: app: httpbin
-
Use the data plane kubeconfig and run the following command to access the httpbin service.
# Set the TOKEN environment variable.
TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.14/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
# Access the httpbin service with the JWT from the sleep pod.
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n"A 200 status code confirms that the request succeeded.
Use a JwksUri address outside the cluster
The following example is based on the HTTP protocol. If you need to use HTTPS to obtain the Jwks, configure an additional destination rule for the ServiceEntry.
Create a ServiceEntry for the remote address.
a. Use the following YAML content to create service-entry.yaml.
apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: external-svc-https namespace: foo spec: addresses: - 11.11.XX.XX # Replace with the address of your external Jwks service. endpoints: - address: 11.11.XX.XX # Replace with the address of your external Jwks service. hosts: - 11.11.XX.XX # Replace with the address of your external Jwks service. location: MESH_EXTERNAL ports: - name: http number: 80 protocol: HTTP - name: https number: 443 protocol: HTTPS resolution: STATICb. Run the following command to deploy the ServiceEntry.
kubectl apply -f service-entry.yaml(Optional) If your jwks service requires the HTTPS protocol, you must configure an additional destination rule for the ServiceEntry.
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: external-svc-https namespace: foo spec: host: <your-service-entry-host> trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 tls: mode: SIMPLECreate a request authentication.
-
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.
In the left-side navigation pane, click Mesh Security CenterRequestAuthentication.
On the RequestAuthentication page, click Create from YAML, select the target Namespaces and any Scenario Template, configure the following YAML, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: foo spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: '${YOUR_EXTERNAL_JWKS_URI}' selector: matchLabels: app: httpbin
-
Run the following commands to set the TOKEN environment variable and perform an access test in the sleep pod.
# Set the TOKEN environment variable.
TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.14/security/tools/jwt/samples/demo.jwt -s)
# Access the httpbin service with the JWT from the sleep pod.
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n"A 200 status code confirms that the request succeeded.
How do I skip JWT authentication for requests to specific paths?
The ASM console provides the authorization policy feature. You can configure an exclusion match in an authorization policy to authenticate requests to paths other than the specified paths.
Deploy and access the services.
a. Deploy the Bookinfo sample application in the cluster associated with the ASM instance. For more information, see Deploy an application in a cluster associated with an ASM instance.
b. Run the following commands to access the following three services and make sure that each path is available.
curl "http://${ASM_GATEWAY_ADDRESS}/productpage" -sS -o /dev/null -w "%{http_code}\n" curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n" curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n"All three services return
200, which indicates that the services are accessible.Create a RequestAuthentication.
-
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.
In the left-side navigation pane, click Mesh Security CenterRequestAuthentication.
On the RequestAuthentication page, click Create from YAML, select the target Namespaces and any Scenario Template, configure the following YAML, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: istio-system spec: jwtRules: - issuer: testing@secure.istio.io jwks: >- { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-e****","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQ****_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5****_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVu****_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoU****_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZ****_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqT****_EyxOGuHJrLsn00****"}]} selector: matchLabels: app: istio-ingressgatewayThis request authentication is applied to the ASM gateway and takes effect on all requests that pass through the gateway. After the RequestAuthentication is configured, requests without a JWT and requests with a correct JWT are both allowed. Only requests that carry an incorrect JWT are rejected.
-
Create an AuthorizationPolicy.
Configure requests to specific paths so that they do not need to carry a JWT, while requests to the other paths must carry a JWT. This topic uses the /productpage path as an example. JWT authentication is not performed for the /productpage path. For the two paths other than the /productpage path, requests must carry a correct JWT to pass.
-
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.
In the left-side navigation pane, click Mesh Security CenterAuthorizationPolicy.
-
On the AuthorizationPolicy page, click Create from YAML, select the target Namespaces and any Scenario Template, configure the following YAML, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: test-exclude namespace: istio-system spec: action: DENY rules: - from: - source: notRequestPrincipals: - '*' to: - operation: notPaths: - /productpage selector: matchLabels: app: istio-ingressgatewayThis AuthorizationPolicy also applies to the ASM gateway. It mainly configures one DENY rule: for requests to paths other than the /productpage path, access is denied if the request does not carry a correct JWT.
Perform an access test.
a. Run the following command to set the JWT carried in requests as the TOKEN environment variable.
export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1****.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5p****.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9****-LS9qd_vpdLG4Tn1A15NxfCjp5f7Q****-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZz****__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCg****_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvH****_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8****b. Run the following commands to access the three service paths.
No requests carry a JWT:
curl "http://${ASM_GATEWAY_ADDRESS}/productpage" -sS -o /dev/null -w "%{http_code}\n"
curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n"
curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n"Expected output:
200
403
403Only the /productpage path can be accessed. All other paths return 403.
All requests carry a JWT:
curl "http://${ASM_GATEWAY_ADDRESS}/productpage" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"
curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/0" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"
curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/1" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"Expected output:
200
200
200All three paths return 200, which indicates that all of them can be accessed.