Decoding the ID Token¶
The ID Token is a security token that contains Claims (fields in token) about the user being authenticated. The Claims contains information such as the issuer, the expiration timestamp, subject identifier, nonce, and other fields depending on the scopes you requested.
We’re going to look at the format of an ID Token (JSON Web Token or JWT) and then examine what comprises the JWT: JOSE header, payload, and signature. At the end of the chapter, we’ll learn to decode and validate ID Tokens.
ID Token as a JSON Web Token (JWT)¶
The ID Token is represented as a JSON Web Token (JWT). The JWT is signed using a JSON Web Signature (JWS) and consists of three parts separated by ‘.’ (period).
An ID Token has the following syntax:
Base64(JOSE header).Base64(Payload).Base64(Signature)
JOSE Header¶
The JOSE header contains information regarding the signing algorithm. The JOSE header has the following fields:
alg
- Identifies the cryptographic algorithm used to secure the JWS.kid
- The hint indicating which key was used to secure the JWS.
JOSE Header Example¶
In the example below, the value of the alg
parameter "ES256"
. This indicates
that the digital signature is encoded using the Elliptic Curve Digital Signature Algorithm (ECDSA)
with the P-256 curve and the SHA-256 cryptographic hash function. See
Creating a JWS with ECDSA P-256 SHA-256, ECDSA P-384 SHA-384, or ECDSA P-521 SHA-512
and Additional Algorithms for more information.
{
"alg":"ES256",
"kid":"87350ad9ce04550819b62079b193a42055a36b71"
}
ID Token Payload¶
The payload contains Claims about the authentication event. The following JSON fields are contained in the payload.
iss
- (Issuer) The Issuer Identifier for the Issuer of the response. Clients must validate that the value is equal tohttps://api.login.yahoo.com
.sub
- (Subject) The unique user identifier.aud
- (Audience) The value of the Client’s ID (client_id
). Clients must verify that it is equal to their Client ID.exp
- (Expiration Time) The expiration for the ID Token. Clients must verify that this expiry time has not passed.iat
- (Issued At) The issue time for the ID Token.nonce
- The nonce passed as a parameter during authorization.at_hash
- (Access Token Hash Value) The Access Token hash (if issued with the flow), which can be used to mitigate cross-site request forgery (CSRF).
Additional Claims¶
Additional Claims may not be needed for SSO but can assist in creating a user account. Yahoo only returns additional Claims for the profile scope.
For the basic profile scope sdps-r
, the
following additional Claims are returned.
name
- the full name of the usergiven_name
- the first name of the userfamily_name
- the last name of the userlocale
- the preferred locale of the user
The extended profile scope sdpp-w
, in addition to the Claims given above,
also returns the following Claims:
email
- the email ID of the useremail_verified
- the Boolean flag letting Clients know if the given email address has been verified by Yahoo.
ID Token Payload Example¶
The example ID Token payload below, in addition to the Claims about the authentication event,
also includes user information such as the user’s name and email address.
These additional Claims were included because the read-write scope to
the Profiles API (sdpp-w
) was sent with the authentication request to Yahoo:
scope=openid sdpp-w
{
"sub": "MCX7TR7RTB5L3YRYR4FIAKX2IE",
"aud": "dj0yJmk9NDdXZzBEcmJ6UjJxJmQ9WVdrOVlVWktjR0ZLTkdFbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD04OQ--",
"email_verified": true,
"iss": "https://api.login.yahoo.com",
"name": "Jasmine Smith",
"exp": 1440569876,
"locale": "en-US",
"given_name": "Jasmine",
"nonce": "YihsFwGKgt3KJUh6tPs2",
"iat": 1440566276,
"family_name": "Smith",
"email": "jasmine_smith@yahoo.com"
}
Signature¶
The last part of the ID Token is the digital signature, which is generated for
the JOSE header and payload data (Base64(JOSE header).Base64(Payload)). Clients
must validate the signature and return an error if the validation fails. To validate
the signature, clients should fetch public keys from the keys endpoint. The endpoint
is available from the jwks_uri
field in the Yahoo Discovery document.
We’ll learn to validate the signature in Validate the ID Token.
Decoding Example¶
We’re going to decode the following ID Token:
/#id_token=eyJhbGciOiJFUzI1NiIsImtpZCI6IjM0NjZkNTFmN2RkMGM3ODA1NjU2ODhjMTgzOTIxODE2YzQ1ODg5YWQifQ.eyJhdWQiOiJkajB5Sm1rOWJrMTVhM0ZYVjJ0NWNEbHRKbVE5V1Zkck9WbFZNWFJrYmtJMVRsUkJiV05IYnpsTlFTMHRKbk05WTI5dWMzVnRaWEp6WldOeVpYUW1lRDA0TUEtLSIsInN1YiI6IlVRSURXSk5XVk5RRDRHWFo1TkdNWlVTVFE0IiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi55YWhvby5jb20iLCJleHAiOjE0NDQ2OTcwNDUsIm5vbmNlIjoiWWloc0Z3R0tndDNLSlVoNnRQczIiLCJpYXQiOjE0NDQ2OTM0NDV9.XiyNdHHHoYqarDZGkhln5sF_SQNNVvV67SZsFAk7yo8NreJjzVw7LmtkwpiUQe87-Km39PeIwf1W_PqEH9RqjA"
First, extract the encoded JOSE header, the payload, and the signature by splitting the ID Token string on “.”:
jose_header = "eyJhbGciOiJFUzI1NiIsImtpZCI6IjM0NjZkNTFmN2RkMGM3ODA1NjU2ODhjMTgzOTIxODE2YzQ1ODg5YWQifQ" payload = "eyJhdWQiOiJkajB5Sm1rOWJrMTVhM0ZYVjJ0NWNEbHRKbVE5V1Zkck9WbFZNWFJrYmtJMVRsUkJiV05IYnpsTlFTMHRKbk05WTI5dWMzVnRaWEp6WldOeVpYUW1lRDA0TUEtLSIsInN1YiI6IlVRSURXSk5XVk5RRDRHWFo1TkdNWlVTVFE0IiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi55YWhvby5jb20iLCJleHAiOjE0NDQ2OTcwNDUsIm5vbmNlIjoiWWloc0Z3R0tndDNLSlVoNnRQczIiLCJpYXQiOjE0NDQ2OTM0NDV9" signature = "XiyNdHHHoYqarDZGkhln5sF_SQNNVvV67SZsFAk7yo8NreJjzVw7LmtkwpiUQe87-Km39PeIwf1W_PqEH9RqjA"
Use a Base64 library to decode the strings. You can use https://www.base64decode.org/ to help you decode the strings for this tutorial:
jose_header = { "alg":"ES256", "kid":"3466d51f7dd0c780565688c183921816c45889ad" } payload = { "aud":"dj0yJmk9bk15a3FXV2t5cDltJmQ9WVdrOVlVMXRkbkI1TlRBbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD04MA--", "sub":"UQIDWJNWVNQD4GXZ5NGMZUSTQ4", "iss":"https://api.login.yahoo.com", "exp":1444697045, "nonce":"YihsFwGKgt3KJUh6tPs2", "iat":1444693445 } signature = "XiyNdHHHoYqarDZGkhln5sF_SQNNVvV67SZsFAk7yo8NreJjzVw7LmtkwpiUQe87-Km39PeIwf1W_PqEH9RqjA"
The
alg
Header Parameter is “ES256”, so you would validate the ECDSA P-256 SHA-256 digital signature contained in the JWS Signature.Congratulations, you have decoded your ID Token. The next step is to validate the ID Token.
Validate the ID Token¶
After decoding your ID Token, you will still need to validate it. Because the validation of an ID Token depends on an expiration time, instead of walking through an example, we’re going to instead provide you with validation steps.
1. Get the Public Keys¶
You’ll need the public keys from Yahoo to validate the signature.
Make a GET request to the URL given by the jwks_uri
parameter in
the Yahoo Discovery document.
In the returned JSON, you’ll see the array keys
containing objects.
2. Find the Matching Public Keys¶
In the keys
array, find the object with the
kid
and alg
fields that have the same values as
those in the JOSE header of your ID Token. Copy the
object as we’ll be using its fields to
validate the signature.
3. Determine the Cryptographic Algorithm¶
The alg
field specifies the cryptographic library to use. For example, if the value for the alg
field is “ES256”,
you would validate the signature using the cryptographic library function for ECDSA P-256 SHA-256.
4. Validate the Signature¶
Use one of the available cryptographic libraries to validate the signature.
For example, if you were using the library Nimbus OAuth 2.0 SDK with OpenID Connect extensions (Java)
to validate the signature, you would get the x
and y
values from the
public keys (see step 2) and use something similar to the code below.
public boolean validateECDSASignatureWithNimbus(String x, String y) throws Throwable {
JWSVerifier verifier = new ECDSAVerifier(new BigInteger(1, Base64.decodeBase64(x)), new BigInteger(1, Base64.decodeBase64(y)));
return SignedJWT.parse(idToken).verify(verifier);
}
5. Check the Expiration¶
You’ll need confirm that the token has not expired by looking at the value of the exp
field
in your ID Token. Confirm that the current UNIX time has not exceeded the value of the exp
field.
6. Confirm the Client ID¶
The aud
field of your ID Token must match the Client ID of the application you created on YDN.
7. Verify the Issuer is Correct¶
Issuer is the Entity (in this case, Yahoo) who set the Claims. Thus, the value of
the iss
field in the ID token must be equal to https://api.login.yahoo.com
.
8. Verify the Nonce is the Same¶
The nonce
value returned in the ID Token should be the same as
the value of the nonce
parameter you transmitted to the authorization endpoint.
This is to verify that you, and not someone else, initiated the request for the ID Token.
9. Use the Claims of the ID Token¶
After all the validations are successful, you can consume the Claims about the authenticated user from the ID Token.