How do I change the format of the scope claim returned in an OAuth 2.0 Access token in Identity Cloud and AM (All versions)?
The purpose of this article is to provide information on changing the format of the scope claim returned in a client-based OAuth 2.0 Access token in ForgeRock Identity Cloud and AM. The default format for the scope claim is an array but some clients require a space-separated list instead.
Overview
By default, the client-based OAuth 2.0 Access token JWT returns the scope claim as an array. For example:"scope": [ "email", "profile" ]Instead of a space-separated string (space delimited), which may be required by some clients. For example:"scope": "email profile"You can reformat the scope claim as a space-separated string via the Access token modification script if required, as described in the following sections:
Identity Cloud
Updating the Access token modification script
You can change the format of the scope claim to a space-separated string as follows:
- In the Identity Cloud admin UI, go to Scripts > Auth Scripts and select the OAuth2 Access Token Modification Script you want to update.
- Update the script to include the following line:accessToken.setField("scope", accessToken.getScope().toArray().join(" "))
- Click Save.
Validating the scope format in the Access token
- Initiate the flow by navigating to a URL such as the following in a browser using Incognito or Browsing mode: https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize?client_id=<client_id>&response_mode=form_post&response_type=code&scope=openid%20profile&redirect_uri=https://httpbin.org/anything
- Authenticate as an end user.
- Allow access to your personal information when prompted for consent.
- Copy the authorization code returned in the browser, for example:"form": { "client_id": "<client_id>", "code": "8xjrUVHHR5i5t_Fkpp3UUr6NBJ8.spkaJhs1d63p7qILFOVrHGaAlp8", ...
- Exchange the authorization code for the access_token:$ curl --location --request POST 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'code=<authorization-code>' \ --data-urlencode 'client_id=<client_id>' \ --data-urlencode 'client_secret=<client_secret>' \ --data-urlencode 'redirect_uri=https://httpbin.org/anything'
- Copy the access_token returned (do not copy the entire response as that also includes the id_token).
- Decode the access_token to verify the scope format. For example, you can use jq on the command line (you can install jq as outlined in Download jq):jq -R 'split(".") | .[1] | @base64d | fromjson' <<< <access_token>Example response showing the scope formatted as a space-separated list:{ "sub": "bddb135d-f6b7-4933-bb9e-525d436d48bb", "cts": "OAUTH2_STATELESS_GRANT", "auth_level": 0, "auditTrackingId": "dbe0d88b-f2cd-480f-ad70-a29250c81b92-1233879", "subname": "bddb135d-f6b7-4933-bb9e-525d436d48bb", "iss": "https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha", "tokenName": "access_token", "token_type": "Bearer", "authGrantId": "TOUEJNkSugx4VsI-Sb80Df1oY14", "aud": "<client_name>", "nbf": 1666784358, "grant_type": "authorization_code", "scope": "openid profile", "auth_time": 1666783409, "realm": "/alpha", "exp": 1666787958, "iat": 1666784358, "expires_in": 3600, "jti": "NtYuS0aSpH0AbeqNTiZS4mC77uE" }
AM
Updating the Access token modification script
You can change the format of the scope claim to a space-separated string as follows:
- In the AM admin UI, go to Realms > [Realm Name] > Scripts and select the OAuth2 Access Token Modification Script you want to update.
- Update the script as follows depending on your AM version:
- AM 7.1.1 and later: add the following line:accessToken.setField("scope", accessToken.getScope().toArray().join(" "))
- Pre-AM 7.1.1: add the following line:accessToken.setField("scope", accessToken.getScope().collect().join(' '))
- Click Save.
Validating the scope format in the Access token
- Initiate the flow by navigating to a URL such as the following in a browser using Incognito or Browsing mode: https://am.example.com:8443/am/oauth2/realms/root/authorize?client_id=<client_id>&response_mode=form_post&response_type=code&scope=openid%20profile&redirect_uri=https://httpbin.org/anything
- Authenticate as an end user.
- Allow access to your personal information when prompted for consent.
- Copy the authorization code returned in the browser, for example:"form": { "client_id": "<client_id>", "code": "8xjrUVHHR5i5t_Fkpp3UUr6NBJ8.spkaJhs1d63p7qILFOVrHGaAlp8", ...
- Exchange the authorization code for the access_token:$ curl --location --request POST 'https://am.example.com:8443/am/oauth2/realms/root/access_token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'code=<authorization-code>' \ --data-urlencode 'client_id=<client_id>' \ --data-urlencode 'client_secret=<client_secret>' \ --data-urlencode 'redirect_uri=https://httpbin.org/anything'
- Copy the access_token returned (do not copy the entire response as that also includes the id_token).
- Decode the access_token to verify the scope format. For example, you can use jq on the command line (you can install jq as outlined in Download jq):jq -R 'split(".") | .[1] | @base64d | fromjson' <<< <access_token>Example response showing the scope formatted as a space-separated list:{ "sub": "demo", "cts": "OAUTH2_STATELESS_GRANT", "auth_level": 0, "auditTrackingId": "47541609-d6d4-48ed-bba8-c93e5cbc34cd-3257", "iss": "https://am.example.com:8443/am/oauth2", "tokenName": "access_token", "token_type": "Bearer", "authGrantId": "tijKVit5RREMJTbC1Ef6k2P-yIY", "aud": "<client_name>", "nbf": 1666782674, "grant_type": "authorization_code", "scope": "openid profile", "auth_time": 1666782620, "realm": "/", "exp": 1666786274, "iat": 1666782674, "expires_in": 3600, "jti": "WLly8dLCIMjO-S4lxmoEsU4jt-U" }
See Also
Identity Cloud
- OAuth 2.0 and OIDC in Identity Cloud
- How do I include additional profile attributes in the OAuth 2.0 Access token in Identity Cloud?
- Token storage location
- Access token modification plugin
AM
- OAuth 2.0 and OIDC in AM
- How do I modify the OAuth2 Access Token Modification script in AM 6.5.2.x, 6.5.3, 6.5.4, 6.5.5 and 7.x?
- Token storage location
- Access token modification plugin
Related Training
N/A
Related Issue Tracker IDs
OPENAM-18241 (Permit OAuth2 Modification Script to return scopes as space delimeter string)