Previously I wrote a post on my first step towards understanding OAuth. This post continues builds on that. OAuth has different types of flows targeting various scenarios or use cases. The main feature that differentiates each of these flows is the grant type.
What exactly is an OAuth grant type?An OAuth grant is something that a client application could exchange for an access token from an Authorization Server. An access token typically represents a user's permission for the client application to access the resources on their behalf
OAuth Grant TypesThe OAuth 2.0 core specification defines four types of grants,
- Authorization code grant
- Implicit grant
- Resource owner credentials grant
- Client credentials grant
In addition to these the core specification also defines a refresh grant type.
There are few new additions to these as well,
- Message authentication code (MAC) tokens
- SAML 2.0 Bearer Assertion Profiles
- JSON Web Token grant
I would like to focus on the JSON Web Token Grant in this post. I hope to write my finding about the rest of the grant types in another post.
What is a JWT Bearer Grant?JSON Web Token bearer grant simply is a json string containing claim values that will be evaluated and validated by the JWT Grant Handlers at the Authroization Server end before issuing an access token. The anatomy of JWT grant,validation process are clearly mentioned in the JSON Web Token (JWT) Profile for OAuth 2.0.
A sample JWT Bearer grant would look like,
a JWT would have a header declaring the algorithms that will be used to hash and sign the JWT to verified by the token endpoint(Grant Handler).
a JWT will be signed and base64 encoded before sending a POST request to a token endpoint to exchange for an access token like given below,
POST /token.oauth2 HTTP/1.1
The assertion value contains three values separated by a dot,
- base64urlencoded JWT header
- base64urlencoded JWT payload
- Signature (signature is calculated by concatenating the base64 encoded header and the base64 encoded payload and signing it)
Signature = sign(base64URlEncode(header) + '.' +
you can easily decode this assertion using jwt-debugger online tool. Simply copy paste the assertion part and you will be enlightened :P
the decoded JWT for the above assertion would be,
please note in the post request body the grant_type parameter takes a value of "urn:ietf:params:oauth:grant-type:jwt-bearer" and the assertion parameter value is the signed base64 encoded JWT. The value of the assertion parameter MUST contain a single JWT.
The claim values and how they are validated will be discussed in the latter part of the post along with validation rules.
How does JWT Bearer Grant Work?
- A client application authenticates at an identity provider and is issued a JSON Web Toke(JWT) containing the claim values which are mentioned in the latter part of the blog.
- The identity provider will issue a JWT after successfully authenticating the client.
- The issued JWT could be used by the client to obtain access tokens from Authorization Servers which the trust the Identity Server that issued the JWT. So simply the Identity Server vouches for your identity and the Authorization Server accepts it trusting the Identity Server.
- After validating the signature of the identity server in the received assertion and validating the claim values in the issued JWT, the authorization server issues an access token.
Above diagram should put it all together for you.
Validating a JSON Web Token Bearer GrantThe validation rules specified to JWT Bearer Grant type are quite simple and have some similarities to SAML Bearer grant type as well.
Before jumping into the validation rules lets look at the claim values/ parameters that come with a valid JWT. There are two types of these claims one set is mandatory and the other, yeah you guessed it right "OPTIONAL".
- Mandatory Values
- iss (issuer)
- sub (subject)
- aud (audience)
- exp (expiration time)
- Optional Values
- nbf (not before)
- iat (issued at)
- jti (json web token Id)
- other custom claims
Rules for validating a JWT bearer grant
- The JWT MUST contain an iss (issuer) claim that contains a unique identifier for the entity that issued the JWT.
The issuer(iss) value is a string that identifies the Identity Provider or the entity that issued the JWT uniquely.
- The JWT MUST contain a sub (subject) claim identifying the principal that is the subject of the JWT.
The subject(sub) value identifies the entity that the identity provider or the entity that issued the JWT vouches for
- The JWT MUST contain an aud (audience) claim containing a value that identifies the authorization server as an intended audience. The token endpoint URL of the authorization server MAY be used as a value for an aud element to identify the authorization server as an intended audience of the JWT.
The audience(aud) value/values are the intended recipients of the JWT denoted by the Identity provider or the JWT issuing entity.
- The JWT MUST contain an exp (expiration) claim that limits the time window during which the JWT can be used. The authorization server MUST reject any JWT with an expiration time that has passed, subject to allowable clock skew between systems. Note that the authorization server may reject JWTs with an exp claim value that is unreasonably far in the future
The expiration time(exp) value limits the usage of the JWT beyond the specified value of time.
- The JWT MAY contain an nbf (not before) claim that identifies the time before which the token MUST NOT be accepted for processing
The not before time(nbf) value forces a JWT to be used only after a specified time.
- The JWT MAY contain an iat (issued at) claim that identifies the time at which the JWT was issued. Note that the authorization server may reject JWTs with an iat claim value that is unreasonably far in the past.
- The JWT MAY contain a jti (JWT ID) claim that provides a unique identifier for the token. The authorization server MAY ensure that JWTs are not replayed by maintaining the set of used jti values for the length of time for which the JWT would be considered valid based on the applicable exp instant.
JWT ID(jti) value is an identity value for the JWT issued. This could be used by the entity validating to prevent used JWTs to be replayed. This value need not be unique always which means thats the a JWT with an already validated jti could be reused after a certain threshold value of time determined by the entity validating and the application context.
- The JWT MAY contain other claims.
JWT may contain claims other than the above mentioned ones. This really is the extension point of the JWT specification. Custom claims could be made mandatory or optional and their validation logic will depend on the application context.
- The JWT MUST be digitally signed or have a Message Authentication Code applied by the issuer. The authorization server MUST reject JWTs with an invalid signature or Message Authentication Code.
The digital signature or the MAC values ensures the integrity of the JWT exchanged between the issuing and the validating entity. The algorithm used for this comes with an inherent vulnerability discussed here.
- The authorization server MUST reject a JWT that is not valid in all other respects per JSON Web Token (JWT) [JWT].