How do I include additional profile attributes in the OIDC ID token in Identity Cloud?
The purpose of this article is to provide information on including additional profile attributes in the OpenID Connect (OIDC) ID token. This can be achieved by adding profile claims to the OIDC Claims script in ForgeRock Identity Cloud. This article uses the extension attributes provided in Identity Cloud (such as frIndexedString1 or frIndexedMultivalued1) to add profile claims to the JWT ID token.
Overview
To include any identity attributes, you must use the equivalent AM attribute name in the OIDC Claims script. For
example, for the extension attributes frIndexedString1
and frIndexedMultivalued1
, you
would use fr-attr-istr1
and fr-attr-imulti1
respectively in your scripts:Display Name | IDM Property | AM Attribute
------------------------------------------------------------------------
Generic Indexed String 1 | frIndexedString1 | fr-attr-istr1
Generic Indexed Multivalue 1 | frIndexedMultivalued1 | fr-attr-imulti1
See User identity attributes and properties reference for mapping details.
Steps involved
- Create a custom OIDC Claims script
- Configure the OAuth 2.0 provider
- Update the OAuth 2.0/OIDC client
- Validate the JWT ID token contains the profile claims
Prerequisites
- You have a working Identity Cloud tenant.
- You have an existing OAuth 2.0/OIDC client in Identity Cloud for use with the OIDC Provider. See Applications for further information.
- You have populated the additional profile attributes for relevant users. The profile claims will not be included in the ID token unless the corresponding attributes are populated.
Note
Writing scripts for OIDC claims is outside the scope of ForgeRock support; if you want more tailored advice, consider engaging Deployment Support Services.
Creating a custom OIDC Claims script
- In the Identity Cloud admin UI, go to Scripts > Auth Scripts > OIDC Claims Script.
- Click the … menu and select Duplicate.
- Enter a unique name for your script and optionally a description.
- Specify the script details:
- Update the profile scope in the
utils.setScopeClaimsMap
section to include the new profile claims. For example, called customMulti and customProfile here: utils.setScopeClaimsMap({ profile: [ 'name', 'family_name', 'given_name', 'customMulti', 'customProfile' ], email: ['email'], address: ['address'], phone: ['phone_number'], }); - Add mapping details for the new profile claims to the
utils.setClaimResolvers
section. For example, with added mapping details for the customMulti and customProfile claims: utils.setClaimResolvers({ /* // An example of a simple claim resolver function that is defined for a claim // directly in the configuration object: custom-claim-name: function (requestedClaim) { // In this case, initially, the claim value comes straight from a user profile attribute value: var claimValue = identity.getAttribute('custom-attribute-name').toArray()[0] // Optionally, provide additional logic for processing (filtering, formatting, etc.) the claim value. // You can use: // requestedClaim.getName() // requestedClaim.getValues() // requestedClaim.getLocale() // requestedClaim.isEssential() return claimValue }, */ /** * The use of utils.getUserProfileClaimResolver shows how * an argument passed to a function that returns a claim resolver * becomes available to the resolver function (via its lexical context). */ name: utils.getUserProfileClaimResolver('cn'), family_name: utils.getUserProfileClaimResolver('sn'), given_name: utils.getUserProfileClaimResolver('givenname'), email: utils.getUserProfileClaimResolver('mail'), address: utils.getAddressClaimResolver( /** * The passed in user profile claim resolver function * can be used by the address claim resolver function * to obtain the claim value to be formatted as per the OIDC specification: * @see https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim. */ utils.getUserProfileClaimResolver('postaladdress') ), phone_number: utils.getUserProfileClaimResolver('telephonenumber'), customMulti: utils.getUserProfileClaimResolver('fr-attr-imulti1'), customProfile: utils.getUserProfileClaimResolver('fr-attr-istr1') }); - Update any other script details as needed.
- Update the profile scope in the
- Click Save and Close.
Configuring the OAuth 2.0 provider
- In the Identity Cloud admin UI, go to Native Consoles > Access Management > Services > OAuth2 Provider > Advanced OpenID Connect and enable Always Return Claims in ID Tokens.
- Click Save Changes.
Updating the OAuth 2.0/OIDC client
- In the Identity Cloud admin UI, go to Native Consoles > Access Management > Applications > OAuth 2.0 > Clients and click the name of your OAuth 2.0/OIDC client.
- Select the OAuth2 Provider Overrides tab and select the custom OIDC Claims script you created above in the OIDC Claims Script field.
- Click Save Changes.
Validating the JWT ID token contains the profile claims
- 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 id_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'
See Identity Cloud Postman collection for further information.
- Copy the id_token returned (do not copy the entire response as that also includes the access_token).
- Decode the id_token to verify that the JWT includes the profile claims. 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' <<< <id_token>Example response showing the profile claims (customMulti and customProfile in this example):{ "at_hash": "PtgPFhutEQ4eHK1_nEVmPQ", "sub": "bddb135d-f6b7-4933-bb9e-525d436d48bb", "customMulti": [ "test1", "test2" ], "auditTrackingId": "6a8d9c63-3154-4094-8713-63e19368d518-27339", "subname": "bddb135d-f6b7-4933-bb9e-525d436d48bb", "iss": "https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha", "tokenName": "id_token", "customProfile": "test", "given_name": "Jane", "sid": "s+g7AVR2lNE6C9t3jx+Tn9VBPO7yVn2xMLHrpH2NAjA=", "aud": "<client_name>", "c_hash": "t8R_lQDDmeQRQe3Pbfn6rg", "acr": "0", "org.forgerock.openidconnect.ops": "5-kDQ_4m8XueDlHI0x6mYuKG9To", "azp": "<client_name>", "auth_time": 1637582507, "name": "Jane Doe", "realm": "/alpha", "exp": 1637586136, "tokenType": "JWTToken", "iat": 1637582536, "family_name": "Doe" }
See Also
Profile scope claims are missing from the OIDC ID token in Identity Cloud
How do I make session properties from a journey available in the OIDC ID token in Identity Cloud?
How do I override claims in the OIDC ID token in Identity Cloud, AM 7.1.x and 7.2.x?
How do I include additional profile attributes in the OAuth 2.0 Access token in Identity Cloud?