Authorization Code Flow with JWT-Secured Authorization Requests (JAR)

JWT-Secured Authorization Request (JAR) is an extension of the OAuth2 protocol and adds a layer of security to protect the integrity of authorization request parameters.

Prerequisites

To use JAR, you must first generate an RSA key pair. Then, register the public key with Auth0 as explained in Configure JWT-Secured Authorization Requests.

During the authorization code flow, the client application takes the parameters they would like to send to the /authorize or /oauth/par endpoints and wraps them in a JSON Web Token (JWT), which they then sign using the private key.

The authorization server verifies the signature with your application's public key. If the signature is valid, the authorization server extracts the request parameters from JAR and processes the request as usual. As a result, the parameter values are guaranteed to come from a known source, and cannot be tampered with or accessed by intermediaries.

Generate the JAR request

To generate a JAR request, you need to first create a JSON Web Token (JWT). Use the Auth0 JWT library to help you generate a JWT in your preferred language.

For a JAR request, the JWT header must contain the following fields:

  • alg: The algorithm used to sign the JWT. Must be either RS256, RS384, or PS256.

  • typ: The type of JWT. Must be either jwt or oauth-authz-req+jwt.

The header may also contain a kid field that identifies the key used to sign the JWT. If a kid is present, Auth0 will look for a public key registered during JAR configuration that has a matching key ID and use that key to verify the JWT’s signature.

Payload

The JWT payload must contain the following claims:

  • iss: This must contain your app’s client_id

  • aud: This must be your tenant’s domain, with the protocol and a trailing forward slash. For example, https://your_domain.auth0.com/

The JWT must also contain any mandatory parameters for the call to /authorize. For example:

  • client_id: This must also contain your app’s client_id

  • response_type: Indicates to Auth0 which OAuth 2.0 flow you want to perform. Use code for Authorization Code Grant Flow.

The JWT may contain any of the optional parameters for the authorization flow that is being requested, such as audience, scope, state, redirect_uri, among others.

In addition, the JWT may contain the following optional claims:

  • iat: Must be a numeric date.

  • nbf: Must be a numeric date, representing a time in the past.

  • exp: Must be a numeric date, representing a time in the future.

  • jti: Must be a string no longer than 64 bytes.

Generate JWT example

The following JavaScript code sample demonstrates how to build and sign a JWT using JavaScript and the jsonwebtoken library. It outputs the generated JWT to the console:

const jwt = require('jsonwebtoken');
const crypto = require("crypto");
const fs = require('fs');

const privateKey = fs.readFileSync('[PATH TO YOUR PEM FILE]');
const client_id = '[YOUR CLIENT ID]';
const nonce = crypto.randomBytes(16).toString('hex');

const requestObject = jwt.sign(
{
  iss: client_id,    
  aud: 'https://your_tenant.auth0.com/', // your tenant's domain
  client_id,
  response_type: "code",
  scope: "openid profile",
  redirect_uri : "https://myapp.com/callback" // your app's callback URL
  nonce
},
privateKey,
{
  keyid: '[YOUR KID]', // optional key id (kid) value from your public key
  algorithm: 'RS256',
  header: {
    typ: 'oauth-authz-req+jwt',
  },
});

console.log(requestObject);

Was this helpful?

/

Call the authorization endpoint

To call the /authorize endpoint using your signed JWT, open a new browser window. Pass your Client ID as the client_id parameter and the signed and URL-encoded JWT as the request parameter.

# MacOS
open "https://your_tenant.auth0.com/authorize?client_id=[YOUR CLIENT ID]&request=[URL ENCODED JWT]"

# Windows
explorer "https://your_tenant.auth0.com/authorize?client_id=[YOUR CLIENT ID]&request=[URL ENCODED JWT]"

Was this helpful?

/

Learn more