JWT FAQ

更新时间:
复制 MD 格式

This topic answers common questions about JSON Web Token (JWT).

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 to use a JwksUri in ASM

To use a JwksUri, you must use Alibaba Cloud Service Mesh (ASM) version 1.13 or later. The configuration process depends on the location of the JwksUri:

  • If the JwksUri points to a service inside the cluster, you can configure it directly.

  • If the JwksUri points to an external service, you must configure a corresponding ServiceEntry.

This topic uses the official Istio JWT and Jwks examples for demonstration. For more information, see JWT and Jwks.

Use an in-cluster JwksUri

This example uses a JwksUri that points to a service within a cluster managed by Service Mesh (ASM). A service named nginx-proxy exposes the /get_jwks endpoint on port 80, which returns the jwks public key. The JwksUri is http://nginx-proxy.{Namespace}.svc.cluster.local:80/get_jwks.

  1. Run the following command to verify that the get_jwks endpoint is accessible.

    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****"}]}

    This output confirms that the get_jwks endpoint is accessible.

  2. Create a RequestAuthentication resource.

    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, click Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. Select the target Namespaces and any Scenario Template, paste 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
  3. Run the following command using the data plane KubeConfig 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 -
    # Send a request with the JWT from the sleep pod to the httpbin service.
    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 indicates a successful request.

Use an external JwksUri

The following example uses the HTTP protocol. If you need to retrieve the Jwks over HTTPS, you must configure an additional destination rule for the ServiceEntry.

  1. Create a ServiceEntry for the remote address.

    1. Create a file named service-entry.yaml with the following content.

      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: STATIC                           

      For more information about ServiceEntry configuration, see ServiceEntry CRD specifications.

    2. Run the following command to deploy the ServiceEntry.

      kubectl apply -f service-entry.yaml
  2. (Optional) If your jwks service requires HTTPS, you must also configure a DestinationRule for the ServiceEntry.

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: external-svc-https
      namespace: foo
    spec:
      host: 
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
        portLevelSettings:
          - port:
              number: 443
            tls:
              mode: SIMPLE
  3. Create a RequestAuthentication resource.

    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, click Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. Select the target Namespaces and any Scenario Template, paste the following YAML, 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_EXTERNAL_JWKS_URI}'
        selector:
          matchLabels:
            app: httpbin
  4. Run the following command to send a request from the sleep pod and test access.

    # Send a request with the JWT from the sleep pod to the httpbin service.
    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 indicates a successful request.

Bypass JWT authentication for specific paths

You can use the authorization policy feature in the ASM console to selectively enforce JWT authentication. By configuring an exclusion match, you can enforce authentication for all paths except those you specify.

  1. Deploy and access the services.

    1. Deploy the Bookinfo sample application in the cluster associated with your ASM instance. For instructions, see Deploy an application in a cluster associated with an ASM instance.

    2. Run the following commands to access the three service paths and ensure they are 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"

      A 200 status code for all three services indicates successful access.

  2. Create a RequestAuthentication resource.

    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, click Mesh Security Center > RequestAuthentication.

    5. On the RequestAuthentication page, click Create from YAML. Select the target Namespaces and any Scenario Template, paste 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-ingressgateway

      This RequestAuthentication policy applies to the ASM gateway and affects all requests that pass through it. After this policy is applied, requests without a JWT or with a valid JWT are allowed, while requests with an invalid JWT are rejected.

  3. Create an AuthorizationPolicy resource.

    Requests to a specific path do not require a JWT, while requests to all other paths must include a JWT. This topic uses the /productpage path as an example. For the /productpage path, JWT authentication is not required. For the two paths other than the /productpage path, requests must include a valid JWT to pass.

    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, click Mesh Security Center > AuthorizationPolicy.

    5. On the AuthorizationPolicy page, click Create from YAML. Select the target Namespaces and any Scenario Template, paste 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-ingressgateway
                                      

      This authorization policy also applies to the ASM gateway. It contains a DENY rule that rejects any request that does not have a valid JWT, except for requests to the /productpage path.

  4. Test access.

    1. Run the following command to set the TOKEN environment variable to the sample JWT.

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

      • Send requests without a JWT:

        curl "http://${ASM_GATEWAY_ADDRESS}/productpage" -sS -o /dev/null  -w "%{http_code}\n"
        200
        
        curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/0" -sS -o /dev/null  -w "%{http_code}\n"
        403
        
        curl "http://${ASM_GATEWAY_ADDRESS}/api/v1/products/1" -sS -o /dev/null  -w "%{http_code}\n"
        403

        Only requests to the /productpage path are successful. Requests to the other paths are rejected with a 403 status code.

      • Send requests with a valid JWT:

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

        All three paths return a 200 status code, indicating that the requests are successful.