JWT profile for authorization
- Endpoints
RFC 7523 JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants defines the use of JWT bearer tokens for requesting access tokens and for client authentication. This page describes how to exchange a JWT bearer token for an access token. For client authentication, refer to JWT profile.
In this profile, the client or another issuer authenticates the resource owner, obtains authorization, and prepares a signed JWT bearer token to use the AM REST APIs. AM does not interact with the resource owner in this grant flow.
You configure AM to trust the issuer with a trusted JWT issuer profile to access the issuer’s public keys. AM supports only asymmetric (public-private key) signing algorithms; HMAC-based signing is not supported. AM validates the JWT signature and content using the trusted JWT issuer profile.
JWT for authorization flow
-
The client directs the resource owner to the issuer for authentication and to obtain authorization.
-
The issuer authenticates the resource owner and obtains consent.
-
On success, the issuer supplies a signed JWT.
-
The issuer redirects the resource owner to the client with the JWT.
-
The client makes a request to exchange the JWT for an access token.
-
AM validates the JWT according to RFC 7523, section 3 with the following additional checks:
-
Match the
iss
claim with the trusted JWT issuer JWT Issuer setting. -
Validate the JWT signature with the trusted JWT issuer’s public key.
AM returns an error if it can’t validate the JWT.
-
-
As authorization server, AM issues an access token to the client.
-
The client uses the token when requesting access to the protected resource.
-
The resource server contacts the authorization server to validate the access token.
-
The authorization server validates the token and responds to the resource server.
-
If the token is valid, the resource server grants the client access to the protected resource.
Demonstrate JWT for authorization flow
Set up a trusted JWT issuer profile
-
In the AM admin UI, go to Realms > Realm Name > Applications > OAuth 2.0 > Trusted JWT Issuer.
-
Click + Add Trusted JWT Issuer Agent, provide the following settings, and then click Create:
- Agent ID
-
An identifier for the profile.
- JWT Issuer
-
The URI to uniquely identify the issuer; this must match the
iss
claim in the JWT.
-
Configure at least the issuer’s public keys by setting either of these fields:
- JWKs URI
-
The URL to the issuer’s JSON Web Key (JWK) set; for example:
https://www.example.com/issuer/jwk_uri
. Use this setting to simplify the process of key rotation.If you configure this field, also check and update the JWKs URI content cache timeout in ms and JWKs URI content cache miss cache time as necessary.
- JWK Set
-
The issuer’s JWK set; for example:
{ "keys": [{ "kty": "RSA", "e": "AQAB", "kid": "example", "alg": "RS256", "n": "uzfshBc3malq8JYIyskEKV6e0X42oAboChGEMKCld92YRsVpiPWc4LpFw2lFhOGy6v5qxnkEsLJf-aMQNSMFkux0356PBGWWWJO1_IlC6EjMJMMvKaCjzZLpEVXEtKj0VjXZl07kQQ8F8SGc_tzp6Sgd-R3nR-tC1HpVAar_DFhISikwm1NyupEhI05sxhyiC_09f5xwY23wwpXx4qrGETsogP8k4FE9jgCiyhafhj9qMHI6skGoLyQgQkqFRn5Krfg6UdPvnEwF5sK3GATWk7sUKR62-ia_986Em0ObSP5230WS8hJO__o3MN-b6qN3o-mdO-a1_E1PRLRY03GHHQ" }] }
-
Configure additional settings as necessary:
- Consented Scopes Claim
-
A JWT claim specifying an array or space-separated allowlist of scopes.
- Resource Owner Identity Claim
-
The JWT claim holding the AM identifier for the resource owner.
When you configure an alternative identifier, the JWT must still include a
sub
claim. - Allowed Subjects
-
Optionally restrict the subjects to the resource owners specified here.
-
Save your changes.
Set up an OAuth 2.0 client
-
Create a confidential OAuth 2.0 client account to get an original token for the subject.
In the AM admin UI, select Realm > Realm Name > Applications > OAuth 2.0 > Clients > + Add Client, and create a new confidential client with the following settings:
- Client ID
-
myClient
- Client secret
-
forgerock
- Redirection URIs
-
https://www.example.com:443/callback
-
Switch to the Advanced tab, add the following setting, and save your work:
- Grant Types
-
Add
JWT Bearer
-
Save your changes.
Set up a resource owner profile
-
In the AM admin UI, select Realms > Realm Name > Identities > + Add Identity and fill the required fields.
-
Record the identifier of the profile to use as the
sub
claim in the JWT.
Issue a signed JWT
As the issuer, prepare and sign the JWT for the client.
The JWT is signed using the issuer’s asymmetric key pair and includes at least the following claims:
Claim | Description |
---|---|
|
A string or array of strings for the intended audience(s), the AM access token endpoint(s). Example: Notice the port number in the URL. |
|
Expiration time in seconds since Jan 1, 1970, UTC. Example: |
|
The JWT issuer’s unique identifier. Example: |
|
The AM identifier for the resource owner. Example: |
Request an access token
As the client, exchange the JWT for an access token:
$ curl \
--request POST \
--user 'myClient:forgerock' \
--data 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer' \
--data 'assertion=<jwt-from-issuer>' \
--data 'redirect_uri=https://www.example.com:443/callback' \
--data 'scope=openid' \
'https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/access_token'
{
"access_token": "<access-token>",
"refresh_token": "<refresh-token>",
"scope": "openid",
"id_token": "<id-token>",
"token_type": "Bearer",
"expires_in": 3599
}
As shown in the example, the request includes these parameters:
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
-
Required for this grant.
assertion=<jwt-from-issuer>
-
The signed JWT.
scope=openid
-
Required if the scopes are not in the JWT and no default scopes are set for the client.
Configure a scripted JWT issuer
Use a script to configure a trusted JWT issuer so that AM can dynamically retrieve the details of an issuer during the JWT profile for authorization grant.
This lets a scripted JWT issuer represent an existing entity in an external system.
For example, if an administrative user creates a service account in IDM, a reference to that service account is provided in the JWT so that the identity can be retrieved and verified by the scripted JWT issuer. The issuer then sends the signed JWT to AM to obtain an access token using the JWT profile for authorization grant.
To configure a scripted JWT issuer, follow these steps:
The examples used in these steps assume an administrator has already created a managed object representing a service account in IDM. |
-
Create a trusted JWT issuer script.
-
In the AM admin UI, go to Realms > Realm Name > Scripts and click New Script.
-
Enter a unique name for your script and select
OAuth2 Trusted JWT Issuer
from the Script Type drop-down list. Click Create. -
Write a script that returns an
org.forgerock.oauth2.core.TrustedJwtIssuerConfig
object.The
TrustedJwtIssuerConfig
object should contain the details of the issuer, the JWK set, and where to locate the subject and scope in the original JWT.Note that scripted JWT issuer scripts can currently only access secrets with IDs that have a prefix of
scripted.jwtissuer
.Example script
( function() { var fr = JavaImporter( org.forgerock.oauth2.core.TrustedJwtIssuerConfig, java.util.HashSet ); var iss = idRepository.getIdentity(issuer); if (iss == null) { logger.message('No issuer found for: ' + issuer); return null; } logger.message('Found for: ' + iss); var jwksAttrs = iss.getAttributeValues('fr-attr-jwks'); if (!jwksAttrs || jwksAttrs.length === 0) { logger.message('No jwk attributes in issuer'); return null; } var jwkSet = jwksAttrs[0]; if (!jwkSet) { logger.message('No jwk set in issuer'); return null; } var config = new fr.TrustedJwtIssuerConfig( issuer, 'sub', 'scope', new fr.HashSet([issuer]), jwkSet, null, null, null ); return config; }());
-
Click Save Changes.
-
-
Configure AM to use the script.
-
In the AM admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Secondary Configurations to configure the OAuth 2.0 provider for the realm.
-
Click Add a Secondary Configuration.
-
Provide a name, select the name of the script you created from the drop-down list, and click Create.
-
The scripted JWT issuer is ready for use.
To reference the external entity to be retrieved by the scripted JWT issuer, the provided
JWT must contain For example, this JWT references a service account with the identifier
|