Access tokens
Use this extension point to modify the key-value pairs in an OAuth 2.0 access token before PingOne Advanced Identity Cloud issues it.
This page demonstrates a simple script. For additional options, refer to the sample access token modification script. Advanced Identity Cloud uses the sample script as the default, commented OAuth 2.0 access token modification script.
Constraints
You can modify both client-side and server-side access tokens. You can also modify macaroons used in place of regular tokens.
PingOne Advanced Identity Cloud stores the modifications in client-side and server-side access tokens. When issuing modified access tokens, consider the following constraints:
-
Removing or changing native properties may render the access token unusable.
PingOne Advanced Identity Cloud relies on native properties that it includes in the access token. If you remove or modify those properties, PingOne Advanced Identity Cloud considers the access token invalid. This can cause the OAuth 2.0 flows to break.
-
Modifying access tokens can significantly increase the size of the token.
Adding key-value pairs to OAuth 2.0 access tokens affects the size of client-side JSON web tokens (JWT), or the size of server-side tokens, if enabled.
Make sure the modified tokens fit within your client and user-agent size limits.
Learn more in Token storage.
Prepare the demonstration
Start by preparing the demonstration:
Sample script
The sample adds key-value pairs to the access token.
It uses methods of the accessToken
and identity
bindings.
-
Create the script.
In the Advanced Identity Cloud admin UI, select Scripts > Auth Scripts > + New Script, and create a new OAuth2 Access Token Modification script.
-
Name the script
Demo access token modification
. -
Replace the default JavaScript with the following and save your script:
(function () { // Add a field next to the access token in the /oauth2/access_token response. accessToken.addExtraData('hello', 'world'); // Add identity profile attribute values to the /oauth2/introspect response. accessToken.setField('mail', identity.getAttribute('mail')); accessToken.setField('phone', identity.getAttribute('telephoneNumber').toArray()[0]); // No return value is expected. }());
The
accessToken
methods update the access token before PingOne Advanced Identity Cloud issues it.The
identity
methods get attribute values from the resource owner’s profile.
OAuth 2.0 client
The OAuth 2.0 client profile in this example overrides the OAuth 2.0 provider settings. This lets you test the script without affecting access tokens issued to other clients.
-
Create a confidential OAuth 2.0 client account.
In the Advanced Identity Cloud admin UI, select Applications > + Add Application, and create a new Web client with the following settings:
- Client ID
-
myClient
- Client Secret
-
forgerock
-
Add the following settings in the client profile and save your work:
- Sign-in URLs
-
https://www.example.com:443/callback
- Scopes
-
access
-
Override OAuth 2.0 provider settings for this client.
Under Native Consoles > Access Management, select Realms > alpha > Applications > OAuth 2.0 > Clients > myClient, switch to the OAuth2 Provider Overrides tab, update the following settings and save your work:
- Enable OAuth2 Provider Overrides
-
Enabled
- Access Token Modification Plugin Type
-
SCRIPTED
- Access Token Modification Script
-
Demo access token modification
Resource owner
An OAuth 2.0 client requests the access token on behalf of a resource owner.
-
Create the OAuth 2.0 resource owner account.
In the Advanced Identity Cloud admin UI, select Identities > Manage > Alpha Realm - Users > + New Alpha Realm - User and fill the required fields.
Record the username and password.
-
Update the following settings in the new user profile and save your work:
- Email Address
-
user@example.com
- Telephone Number
-
(555) 323-1234
Test the demonstration
After preparing the demonstration, test your work using HTTP calls to REST endpoints.
The demonstration uses the Authorization code grant flow:
-
The resource owner authenticates to obtain an SSO token.
-
The client relies on Implied Consent being enabled (default). It assumes the resource owner grants the client access.
-
The client requests the authorization code and exchanges it for an access token your script modified.
-
The client introspects the access token.
Follow these steps:
-
Authenticate as the resource owner:
curl \ --request POST \ --header 'Content-Type: application/json' \ --header 'X-OpenAM-Username: <resource-owner-username>' \ --header 'X-OpenAM-Password: <resource-owner-password>' \ --header 'Accept-API-Version: resource=2.0, protocol=1.0' \ 'https://<tenant-env-fqdn>/am/json/realms/root/realms/alpha/authenticate' {"tokenId":"<resource-owner-tokenId>","successUrl":"/enduser/?realm=/alpha","realm":"/alpha"}
-
Request the authorization code as the client:
curl \ --dump-header - \ --request POST \ --cookie '<session-cookie-name>=<resource-owner-tokenId>' \ --data 'scope=access' \ --data 'response_type=code' \ --data 'client_id=myClient' \ --data 'csrf=<resource-owner-tokenId>' \ --data 'redirect_uri=https://www.example.com:443/callback' \ --data 'state=abc123' \ --data 'decision=allow' \ 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize' ... location: https://www.example.com:443/callback?code=<authorization-code>&iss=https%3A%2F%2F... ...
-
Exchange the authorization code for an access token as the client:
curl \ --request POST \ --user 'myClient:forgerock' \ --data 'grant_type=authorization_code' \ --data 'code=<authorization-code>' \ --data 'redirect_uri=https://www.example.com:443/callback' \ 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token' { "access_token": "<access-token>", "refresh_token": "<refresh-token>", "scope": "access", "hello": "world", "token_type": "Bearer", "expires_in": 3599 }
The script added
"hello": "world"
alongside the access token in the /oauth2/access_token response. -
Introspect the access token as the client:
curl \ --request POST \ --user 'myClient:forgerock' \ --data 'token=qOshQEHOg2r-AU2kmJgBzfUEC5M' \ 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/introspect' { "active": true, "scope": "access", "realm": "/alpha", "client_id": "myClient", "user_id": "014c54bd-6078-4639-8316-8ce0e7746fa4", "username": "014c54bd-6078-4639-8316-8ce0e7746fa4", "token_type": "Bearer", "exp": 1668597726, "sub": "014c54bd-6078-4639-8316-8ce0e7746fa4", "subname": "014c54bd-6078-4639-8316-8ce0e7746fa4", "iss": "https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha", "auth_level": 0, "authGrantId": "dNJ9r6jMA6yZ88nnho7f6KDCESk", "auditTrackingId": "3819034a-4294-4b56-94ea-8e6015869083-2607123", "mail": ["user@example.com"], "phone": "(555) 323-1234" }
The script added
"mail": ["user@example.com"]
and"phone": "(555) 323-1234"
.
Use a validated script
Test your access token modification scripts as you did for the demonstration. After validating your script with OAuth 2.0 provider overrides in your test client, you can update the OAuth 2.0 provider configuration to use the script in one of the following ways:
-
Under Native Consoles > Access Management, select Realms > realm > Services > OAuth2 Provider, switch to the Plugins tab, edit the Access Token Modification Script, and save your work.
-
In the Advanced Identity Cloud admin UI, select Scripts > Auth Scripts > OAuth2 Access Token Modification Script, and replace the script content with your validated script.
Available objects
PingOne Advanced Identity Cloud injects the following objects into the execution context of an OAuth 2.0 access token modification script:
Binding | Information | ||
---|---|---|---|
|
The OAuth 2.0 access token. For details, refer to AccessToken. |
||
|
A map of properties configured in the client profile. The map has the following keys:
The map is |
||
|
An HTTP client for making external HTTP requests. |
||
|
An identity PingOne Advanced Identity Cloud can access. For details, refer to AMIdentity. |
||
|
Write a message to the PingOne Advanced Identity Cloud debug log. Always present in all extension scripts. In Advanced Identity Cloud, this corresponds to the Logger names use the format Learn more about debug logs in Get audit and debug logs. |
||
|
A map of the properties present in the request. The map has the following keys:
|
||
|
The display name of the script. |
||
|
An array of the requested scopes; for example, |
||
|
The user’s session object if the request contains a session cookie. For details, refer to SSOToken. |