Skip to main content

JWT Bearer Grant - OAuth2

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 Types

The 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
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer &assertion=eyJhbGciOiJSUzI1NiJ9.

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,

  "alg": "RS256"
  "exp": 1427395083,
  "sub": "farazath",
  "nbf": 1427394483,
  "aud": [
  "iss": "LOCAL",
  "jti": "Token56756",
  "iat": 1427394483

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?

By looking at the above diagram, you should be able to get a basic idea. Let me go through the steps

  • 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 Grant

The 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].


    Popular posts from this blog

    Trying out OAuth2 Authorization Code grant with WSO2 Identity Server without the PlayGround2 App

    The first thing I did after joining the WSO2 Identity Server team was to test the WSO2 Identity Server 5.2.0-beta pack. I had some experience playing around with OAuth so I started testing OAuth scenarios. I was able to test most grant types with ease. Then came the authorization code grant type. The usual way to test it was to setup the playground2 app and test. I wanted to look for an alternate way to test the Authorization grant type without setting up the app (partly because I was lazy to download tomcat etc. :P )

    So with the help of my team member Pushpalanka, I found an alternate way to get an access token by simply using a browser redirect and a curl command. So I wanted to make a note in case someone wanted to do the same :)

    1. First, log in to the Identity Server management console.
           the defaults are,
                      username = admin                   password = admin

    2. Go to the Service Provider configuration page and create a Service Provide, let's say SP_lazy…

    OAuth2 Authorization Code flow without client secret using WSO2 Identity Server

    Quoting from

    Single-page apps (or browser-based apps) run entirely in the browser after loading the source code from a web page. Since the entire source code is available to the browser, they cannot maintain the confidentiality of their client secret, so the secret is not used in this case. The flow is exactly the same as the authorization code flow above, but at the last step, the authorization code is exchanged for an access token without using the client secret.  Note: Previously, it was recommended that browser-based apps use the "Implicit" flow, which returns an access token immediately and does not have a token exchange step. In the time since the spec was originally written, the industry best practice has changed to recommend that the authorization code flow be used without the client secret. This provides more opportunities to create a secure flow, such as using the state parameter. References: RedhatDeutsche TelekomS…