JSON Web Tokens (JWTs)

Configuring the JWT Bearer Flow

The JWT Bearer flow trades a signed JWT from an external token service in exchange for an access token from Liferay. To use this flow, create an OAuth 2 client and configure an incoming assertion issuer that matches the JWT’s iss, sub, and signing keys. After configuring the issuer, update your OAuth 2 client to support the JWT_BEARER authorization type. The token service then sends a signed assertion to Liferay’s token endpoint, and Liferay returns an access token if the assertion is valid.

See Assertion as Authorization Grant for background on how the flow works.

Configuring the Incoming Assertion Issuer

  1. Open the Global Menu (Applications Menu icon) and navigate to Control PanelInstance Settings.

  2. In the OAuth 2 Incoming Assertion Configuration, click Add.

  3. Enter the name of the issuer, a JSON web key set, and the user authentication type.

    Enter details for the issuer, JWKS, and user authentication type.

  4. Click Save.

The issuer value should be equal to the iss value in the issuer’s JWT assertion. The user authentication type value must match the sub value in the JWT assertion. You may need additional configuration in your token service to map these values.

The JSON web key set is usually available at the JWKS URI of your token service. For instance, if you’re using Keycloak, the JWKS URI is available at

http://{hostname}/realms/{realm_name}/protocol/openid-connect/certs

Audience Claim Requirement

The incoming JWT assertion must include an aud claim that matches Liferay’s token endpoint. Liferay returns invalid_grant when the audience does not match.

Example for a local instance:

aud: http://localhost:8080/o/oauth2/token

Use the exact token endpoint URL of your Liferay instance.

Note

The aud claim may contain multiple values (a JSON array). Liferay only requires that one entry matches the token endpoint. Additional audiences added by the external Identity Provider are ignored.

Troubleshooting Invalid Grant Errors

The invalid_grant error lacks detail. Add a logger to print the specific validation errors and so you can confirm which JWT claims are missing or incorrect.

  1. Open the Global Menu (Global Menu), go to the Control Panel tab, and click Server Administration.

  2. Open the Log Levels tab and click New.

  3. Set the logger name to com.liferay.oauth2.provider.rest.internal.endpoint.access.token.grant.handler and the log level to DEBUG.

  4. Click Save.

This log output helps pinpoint the exact issue in the incoming assertion, making it easier to adjust your JWT configuration.

Enabling the JWT Bearer Flow

After configuring the incoming assertion issuer, ensure you’ve enabled the JWT Bearer flow for your client.

  1. Open the Global Menu (Applications Menu icon) and navigate to Control PanelOAuth 2 Administration.

  2. Select your OAuth 2 client and scroll down to Allowed Authorization Types.

  3. Check the JWT_BEARER checkbox.

  4. Click Save.

Getting an Access Token from Liferay

Once you’ve configured an incoming assertion issuer and enabled the JWT_BEARER flow for your client, you can start getting access tokens from Liferay.

If you’re using a confidential client, you must initiate a POST request to Liferay’s token URL https://{hostname}/o/oauth2/token with the following parameters in the body (encoded as application/x-www-form-urlencoded):

client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=JWT assertion from the token service

Below is a sample token request made to Liferay using a JWT assertion from Keycloak. Keycloak is configured as an incoming assertion issuer in Liferay.

Liferay issues an access token for the JWT Bearer flow.