Verifying Azure Active Directory JWT Tokens

When working with OAuth and Open ID Connect, there are times when you’ll want to inspect the contents of id, access or refresh tokens. The website https://jwt.io is useful as you can drop in the token in the pane on the left, and the site dynamically decodes the header, body and signature for the JWT.

image

Unfortunately by itself the signature on the JWT can’t be verified as the website doesn’t know what key to use to validate the signature. The header of the JWT does provide information about the algorithm used (ie RS256) and the id of the key used but this by itself isn’t enough to locate the key to be used.

image

As RS256 is a public/private key algorithm, there is a private key, which the issuer holds, and a public key which is available to anyone to access. The former is used to generate the signature for a JWT; the later can then be used to validate the signature. To find the public key to use to validate the signature I’ll start with the OpenID Connect configuration document, which is available for any tenant at:

https://login.microsoftonline.com/{tenantId}/.well-known/openid-configuration

eg https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/.well-known/openid-configuration

The returned configuration document contains an attribute, jwks_uri, which points at https://login.microsoftonline.com/common/discovery/keys

image

Loading the jwks_uri returns another JSON document which lists a number of keys. Now we can use the kid from the header of the JWT to identify which key to use, in this case the first key in the list.

image

Attempting to simply copy the x5c value from the list of keys into the Public Key or Certificate box on the jwt.io website will still not verify the signature of the JWT. In order to verify the signature, wrap the key in BEGIN and END CERTIFICATE markers as follows:

—–BEGIN CERTIFICATE—–
MIIDBTCCAe2gAwIBAgIQEsuEXXy6BbJCK3bMU6GZ/TANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE2MTEyNjAwMDAwMFoXDTE4MTEyNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd6Sq5aJ/zYB8AbWpQWNn+zcnadhcMYezFvPm85NH4VQohTm+FMo3IIJl6JASPSK13m9er3jgPXZuDkdrEDHsF+QMEvqmffS2wHh3tKzasw4U0jRTYB0HSCbmnw9HpUnv/UJ0X/athO2GRmL+KA2eSGmb4+5oOQCQ+qbaRXic/RkAOLIw1z63kRneLwduQMsFNJ8FZbWkQFj3TtF5SL13P2s/0PnrqwGD59zcbDu9oHOtciu0h++YhF5CWdWEIgafcZk9m+8eY12BKamvPdBnyfpz6GVTenJQe2M+AGz5RSNshvI976VUbBiaIeNzvzaG91m62kFWLRqE3igq6D02ECAwEAAaMhMB8wHQYDVR0OBBYEFAgoZ9HLgFxH2VFGP6PGc4nFizD2MA0GCSqGSIb3DQEBCwUAA4IBAQBSFXalwSJP/jihg04oJUMV2MTbuWtuFhdrdXiIye+UNc/RX02Q9rxd46BfGeKEBflUgNfEHgyEiWTSLAOSDK70vu+ceCVQCGIQPjnGyYOpm80qAj/DNWZujVcSTTV3KZjMFsBVP7miQowfJQ58u9h8yuJHNhPpB2vOFmNhm4uZq3ve529Xt51HdtQGG9+Z9n1DhObqzkbz8xEFjA+KdfcRsZXa14ZkpAOe35VgyY0f8x34Y0LPfibWcNpfp0AhxKzyqT1GRRlKTjiBA6WNJIJIEeqh/nfOnwM0UQKRnt+2qeV3u00a5lrvJtEy7nq+s7xYtpVAsCvn5T0U1/8IHkxt
—–END CERTIFICATE—–

Entering the wrapped key into the Public Key or Certificate box on the jwt.io website will successfully verify the signature of the JWT.

image

9 thoughts on “Verifying Azure Active Directory JWT Tokens”

  1. HI Nick,
    it is good article and neatly explain with clear text.
    In my case in her “kid”: “xxxx” is exist but same key when i looking jwts_keys 3 list is coming but none of the KID key is matching with header.
    what colud be the issue.
    access_token generated on Azure Cloud using that token i am connectiong Windows Authentication API hosted in on-premises web server using Application Proxy connector.

    please guide me

    Reply
  2. Hei Nick,

    I am facing the similar issue which jainshankar is facing, any luck with this. ?
    KeyId is not present in public keys.

    Thanks & Regards

    Reply
  3. I was having a similar issue and found:
    If your app has custom signing keys as a result of using the claims-mapping feature,
    you must append an appid query parameter containing the app ID to get a jwks_uri pointing to your app’s signing key information, which should be used for validation.
    Like this: https://login.microsoftonline.com/{tenant}/discovery/keys?appid={appid}
    https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#validating-the-signature

    Reply
  4. Hi Nick.

    I have received Token from AZURE AD and can browse the public key from URL-https://login.microsoftonline.com/{tenant}/discovery/keys?appid={appid}
    I found the Kid from the header from the token and find the x5c value from keys. and tried to validate the signature via- https://jwt.io and paste the value inside
    ——–BEGIN CERTIFICATE—–
    X5c value
    —–END CERTIFICATE—–
    JWT.io display invalid signature. Please suggest.

    Reply
        • For those having same issue.
          Problem might be with number of dashes.
          jwt.io verifies signature only with exactly 5 dashes before and after the BEGIN/END CERTIFICATE. Also make sure, thare aren’t any spaces between text and dashes.

          —–BEGIN CERTIFICATE—–
          x5c cert
          —–END CERTIFICATE—–

          Reply

Leave a comment