
Validating an OpenID Connect ID Token
On this page
This article describes how to validate an OpenID Connect ID Token. What each part of the token means and when to use them.
The ID Token is a signed JSON Web Token (JWT). The JWT format is specified in RFC7519.
The ID Token is a JWT with specified contents, defined by the OpenID Foundation in the OpenID Connect Core Specification specification.
The ID Token JWT
An ID Token is always a JWT token. It cannot be issued as an opaque reference token.
The ID Token is an encoded and signed JSON Web Token (JWT) containing claims issued by the OpenID Connect Provider (the Curity Identity Server).
The ID token consists of three main parts:
header
- Metadata about the token and its cryptographic algorithmpayload
- Claims about the issuer, the user and user authorizationsignature
- For verification of the integrity of the token
The parts are separated with a .
period in the encoded token:
Example:
eyJraWQiOiItMzgwNzQ4MTIiLCJ4NXQiOiJNUi1wR1RhODY2UmRaTGpONlZ3cmZheTkwN2ciLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiQ2djcDVvaWtzdDM4M2NBYl9KNU1WUSIsImRlbGVnYXRpb25faWQiOiI4MDkxZDEzMi02OGRkLTQ2YzMtYWRiZC0xYzgzNjQzYzRhNTciLCJhY3IiOiJ1cm46c2U6Y3VyaXR5OmF1dGhlbnRpY2F0aW9uOmh0bWwtZm9ybTpodG1sU3FsIiwic19oYXNoIjoiYXFpRFYxQ3k2U0NzZmEyQXlOcjVfUSIsImF6cCI6ImNsaWVudC1vbmUiLCJhdXRoX3RpbWUiOjE1NTA4MzMxNDgsIm5vbmNlIjoiMTU1MDgzMzExODA5Ni1IVm0iLCJleHAiOjE1NTA4MzY4MDcsIm5iZiI6MTU1MDgzMzIwNywianRpIjoiZTc1ZmQ0ZTctNjVjNC00ZmVlLWJjYjYtZGUxZjI5OTYwMTViIiwiaXNzIjoiaHR0cHM6Ly9leGFtcGxlLmN1cml0eS5pbyIsImF1ZCI6ImNsaWVudC1vbmUiLCJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNTUwODMzMjA3LCJwdXJwb3NlIjoiaWQifQ.kKq2h2x20K-eXtoAeTFsjOIFzmfTjR8zP5F48qTQAkAK9qLKJCQkJ9UkAmHUw9BVgfb2zxLiRG6e5ACTpmxR_Mqv4mFeGyBR1faLJTXwdmiuJqqBcCKWS48KmhE-7XkxoF9nuiU_aaQArVn-Cx3qI2pQ945qUcXa47J2vn0xxGpm82VLQNfCsttT4M7HU-SjvTHOqS439bKl4gIcg-MIxmog08J5GdQpmyt7p2-cGvwd4iQVcd5t6sL0hcw5Q36sLSRnms4e8F9xWLZS2cD6ppdv4h8nr9whQB5NtIbw10f8rgy6o6vODu91JoxrAodTyu6QlVtN6uugicAR4OWs5w
OAuth Tools
You can use Curity's OAuth Tools to decode and analyze JWTs to try them out.
Decoding
To decode the token, you need to do a base64url decode
of each part. The decoded parts will be represented as JSON content data. Split the token on the .
period.
Header
The header contains metadata, such as and the hash algorithm used for the token contents, and (somewhat redundantly for our purposes) the type of token.
Example:
{"kid": "-38074812","x5t": "MR-pGTa866RdZLjN6Vwrfay907g","alg": "RS256"}
The header should be used to figure out what key to use when validating the token. There are a few options but the most common ones are:
kid : The key id. The key is found on the Json Web Key Set (JWKS) endpoint of the issuer.
x5t or x5t#256 : The fingerprint of the certificate to use hashed with SHA1 or SHA256.
alg : The algorithm used when signing the token. This should be a strong enough algorithm. Do not rely on this solely. Libraries should block algorithms such as none to prevent attacks.
x5t
is commonly used when the certificate is pre-distributed to the clients, and kid
when JWKS is used.
For more information, see the Registered Header Parameter Names section of RFC7515 - JSON Web Signature.
Payload
The Payload contains the claims for use by the client. When decoding the first thing to look for is the iss
issuer field. It shows who issued the token and must be an HTTPS url. This is important for the following reasons:
- Only trust tokens from known issuers
- Use the issuer to find the JWKS endpoint via the OpenID Connect Metadata
Example:
{"at_hash": "Cgcp5oikst383cAb_J5MVQ","delegation_id": "8091d132-68dd-46c3-adbd-1c83643c4a57","acr": "urn:se:curity:authentication:html-form:htmlSql","s_hash": "aqiDV1Cy6SCsfa2AyNr5_Q","azp": "client-one","auth_time": 1550833148,"nonce": "1550833118096-HVm","exp": 1550836807,"nbf": 1550833207,"jti": "e75fd4e7-65c4-4fee-bcb6-de1f2996015b","iss": "https://example.curity.io","aud": "client-one","sub": "johndoe","iat": 1550833207,"purpose": "id"}
Signature
The last part of the ID Token is the signature, which you use to to verify that the token was issued by the trusted issuer and not tampered with in route.
kKq2h2x20K-eXtoAeTFsjOIFzmfTjR8zP5F48qTQAkAK9qLKJCQkJ9UkAmHUw9BVgfb2zxLiRG6e5ACTpmxR_Mqv4mFeGyBR1faLJTXwdmiuJqqBcCKWS48KmhE-7XkxoF9nuiU_aaQArVn-Cx3qI2pQ945qUcXa47J2vn0xxGpm82VLQNfCsttT4M7HU-SjvTHOqS439bKl4gIcg-MIxmog08J5GdQpmyt7p2-cGvwd4iQVcd5t6sL0hcw5Q36sLSRnms4e8F9xWLZS2cD6ppdv4h8nr9whQB5NtIbw10f8rgy6o6vODu91JoxrAodTyu6QlVtN6uugicAR4OWs5w
Validating the token
After initial decoding the token can be validated.
Signature
The signature is generated using the hashing algorithm from the token header.
To verify the signature, you must:
- Check the signing algorithm
- Verify signature with a public key
Check Algorithm
The alg
value for the signature should be of the expected type. (Whitelist the types your organization allows)
Verify signature
To verify the signature you should:
- Retrieve the public key by using the
x5t
orkid
parameter. - Break off the signature from the message leaving the
header.payload
encoded - Convert the header+payload segment to an ASCII array
- Base64Url decode the signature
- Use the decoded signature to validate the header+payload ASCII byte array
Verifying Standard Claims
Once the token has been received and decoded, you can validate the claims it contains, to make sure that they match the expected values:
Claim | Description | Comment |
---|---|---|
acr | Authentication method used | Should match the acr_values request parameter (if it was sent in the request). |
iss | Issuer | Identifier for the creator of the token. Must be a plain https:// URL. |
sub | Subject | Identifier for the authenticated user. |
aud | Audience | Expected recipient(s). Must contain some identifier for client, for example the Client ID or domain. |
iat | Issued At | When the ID Token was issued. |
auth_time | Authentication Time | When the user last was logged in without SSO. |
jti | Token identifier | A unique identifier for this token. Can be used to prevent replays |
nonce | Nonce | If the client passed in a nonce when requesting the token it must be present here |
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial