All Products
Search
Document Center

Alibaba Cloud Service Mesh:FAQ about JWT

Last Updated:Mar 14, 2024

This topic provides answers to some frequently asked questions about JSON Web Token (JWT).

What JWT algorithms does ASM support?

  • A Service Mesh (ASM) instance of a version earlier than V1.13 only supports the RSA algorithm.

  • An ASM instance of V1.13 or later supports ES256, ES384, ES512, HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, and EdDSA algorithms.

How do I use the jwksUri parameter in ASM?

You can use the jwksUri parameter only in a Service Mesh instance of V1.13 or later. The method varies depending on the scenario:

  • When you want to specify the URL of a service in the Container Service for Kubernetes (ACK) cluster managed by ASM, you can use the jwksUri parameter directly.

  • When you want to specify the URL of a service that is not deployed in the ACK cluster managed by ASM, you must configure the corresponding service entry.

In this example, the official JWT and JSON Web Key Set (JWKS) of Istio are used. For more information, see the sample JWT and JWKS of Istio.

jwksUri specifies the address of a service in the ACK cluster managed by ASM

In this example, jwksUri specifies the address of the nginx-proxy service in a cluster managed by Service Mesh. You can obtain the public keys of JWKS over port 80 from this address. The jwksUri is http://nginx-proxy.{Namespace}.svc.cluster.local:80/get_jwks.

  1. Run the following command to check whether get_jwks of the cluster is usable:

    curl nginx-proxy/get_jwks

    Expected output:

    { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-e****","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65p****-P7KfIupjf59vsdo91bSP9C8H07pSAGQ****_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5****_pbhLdKXbi66GlVeK6ABZOUW3WYt****-91gVuoeJT_DwtGGcp4ignkgXfkiE****-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoU****_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZ****_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqT****_EyxOGuHJrLsn00****"}]}

    The preceding output indicates that get_jwks is usable.

  2. Create a request authentication policy.

    1. Log on to the ASM console.

    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    3. 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.

    4. In the left-side navigation pane, choose Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. On the page that appears, select the namespace where you want to create the request authentication policy and a scenario-specific template, copy the following content to the YAML editor, 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
  3. Use kubectl to connect to the data plane based on the information in the KubeConfig file, 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 application from the pod where the sleep application resides by using a request with a JWT. 
    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"

    If status code 200 is returned, the operation succeeds.

jwksUri specifies the address of a service that is not deployed in the ACK cluster managed by ASM

In this example, the HTTP protocol is used. To use HTTPS to obtain JWKS, configure a destination rule for the service entry.

  1. Create a service entry for the service.

    1. Create a file named service-entry.yaml and copy the following content to the file:

      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: external-svc-https
        namespace: foo
      spec:
        addresses:
          - 11.11.XX.XX   # Replace this variable with your jwksUri. 
        endpoints:
          - address: 11.11.XX.XX  # Replace this variable with your jwksUri. 
        hosts:
          - 11.11.XX.XX  # Replace this variable with your jwksUri. 
        location: MESH_EXTERNAL
        ports:
          - name: http
            number: 80
            protocol: HTTP
        resolution: STATIC                           
    2. Run the following command to create the service entry:

      kubectl apply -f service-entry.yaml
  2. Create a request authentication policy.

    1. Log on to the ASM console.

    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    3. 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.

    4. In the left-side navigation pane, choose Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. On the page that appears, select the namespace where you want to create the request authentication policy and a scenario-specific template, copy the following content to the YAML editor, and then click Create:

      apiVersion: security.istio.io/v1beta1
      kind: RequestAuthentication
      metadata:
        name: jwt-example
        namespace: foo
      spec:
        jwtRules:
          - issuer: tes****@secure.istio.io
            jwksUri: '${Your jwksUri}'
        selector:
          matchLabels:
            app: httpbin
  3. Run the following command to access the httpbin application in the pod where the sleep application resides:

    # Access the httpbin application from the pod where the sleep application resides by using a request with a JWT. 
    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"

    If status code 200 is returned, the operation succeeds.

How do I configure JWT authentication when I do not want to authenticate requests bound for specific paths?

You can set the action parameter to DENY and specify the paths when you configure the YAML file of an authorization policy in the ASM console.

  1. Deploy a sample application and access the application.

    1. Deploy the Bookinfo application in the ASM instance. For more information, see Deploy an application in an ASM instance.

    2. Run the following commands to access the three services to ensure that all paths are accessible:

      curl "http://${IP address of the ingress gateway}/productpage" -sS -o /dev/null -w "%{http_code}\n"
      curl "http://${IP address of the ingress gateway}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n"
      curl "http://${IP address of the ingress gateway}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n"

      If status code 200 is returned in every command output, the operation succeeds.

  2. Create a request authentication policy.

    1. Log on to the ASM console.

    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    3. 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.

    4. In the left-side navigation pane, choose Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. On the page that appears, select the namespace where you want to create the request authentication policy and a scenario-specific template, copy the following content to the YAML editor, 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-ingressgateway

      This request authentication policy applies to the ingress gateway, and all the requests that pass through the gateway need to be authenticated. Requests with valid JWTs or with no JWTs are allowed whereas requests with invalid JWTs are rejected.

  3. Create an authorization policy that allows requests with no JWTs to access certain paths.

    In this example, requests bound for the /productpage path do not need to pass JWT authentication whereas requests bound for the other two paths must carry valid JWTs.

    1. Log on to the ASM console.

    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    3. 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.

    4. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy.

    5. On the AuthorizationPolicy page, click Create from YAML. On the page that appears, select the namespace where you want to create the authorization policy and a scenario-specific template, copy the following content to the YAML editor, 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-ingressgateway
                                      

      This authorization policy also applies to the ingress gateway. A DENY rule is configured to reject all the requests without valid JWTs to paths except the /productpage path.

  4. Perform an access test.

    1. Run the following command to set the JWT to the Token environment variable:

      export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1****.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5p****.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9****-LS9qd_vpdLG4Tn1A15NxfCjp5f7Q****-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZz****__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCg****_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvH****_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8****
    2. Run the following commands to access the three services.

      • Every request does not carry a JWT:

        curl "http://${IP address of the ingress gateway}/productpage" -sS -o /dev/null -w "%{http_code}\n"
        200
        
        curl "http://${IP address of the ingress gateway}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n"
        403
        
        curl "http://${IP address of the ingress gateway}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n"
        403

        The output shows that only the /productpage path is accessible whereas the other two paths cannot be accessed and status code 403 is returned.

      • Every request carries a JWT:

        curl "http://${IP address of the ingress gateway}/productpage" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"
        200
        
        curl "http://${IP address of the ingress gateway}/api/v1/products/0" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"
        200
        
        curl "http://${IP address of the ingress gateway}/api/v1/products/1" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"
        200

        Status code 200 is returned for each operation, indicating that all the three paths are accessible.