Identity Cloud

OpenID Connect 1.0 claims

Use this extension point to modify and override claims in an ID token and in the response to a /userinfo request.

This page demonstrates changes to the default OpenID Connect 1.0 claims extension script to retrieve custom attribute values from the end user profile.

For additional examples, refer to the following Knowledge Base articles:

Prepare the demonstration

Start by preparing the demonstration:

Sample script

The sample replaces the locale and zoneinfo claims with custom claims from end user profile attributes.

  1. Create the script.

    In the Identity Cloud admin UI, select Scripts > Auth Scripts > + New Script, and create a new OIDC Claims script.

  2. Name the script Demo OIDC claims.

  3. Edit the default JavaScript as follows and save your script.

    • In the utils.setScopeClaimsMap function call, replace the locale and zoneinfo fields with references to the custom claims custom_string and custom_multivalue:

      utils.setScopeClaimsMap({
          profile: [
              'name',
              'family_name',
              'given_name',
              'custom_string',
              'custom_multivalue'
          ],
          email: ['email'],
          address: ['address'],
          phone: ['phone_number']
      });
    • In the utils.setClaimResolvers function call, replace the locale and zoneinfo definitions with definitions for the custom claims:

      utils.setClaimResolvers({
          name: utils.getUserProfileClaimResolver('cn'),
          family_name: utils.getUserProfileClaimResolver('sn'),
          given_name: utils.getUserProfileClaimResolver('givenname'),
          custom_string: utils.getUserProfileClaimResolver('fr-attr-str1'),
          custom_multivalue: utils.getUserProfileClaimResolver('fr-attr-multi1'),
          email: utils.getUserProfileClaimResolver('mail'),
          address: utils.getAddressClaimResolver(
              // ...
              utils.getUserProfileClaimResolver('postaladdress')
          ),
          phone_number: utils.getUserProfileClaimResolver('telephonenumber')});
      });

      The AM attributes fr-attr-str1 and fr-attr-multi1 are end user profile attributes. You set their values when creating the end user profile.

Relying party

This OpenID Connect 1.0 relying party (client) profile overrides the AM OAuth 2.0 provider settings. The override lets you test the script without affecting ID and access tokens issued to other applications.

  1. Create a confidential OAuth 2.0 client account.

    In the Identity Cloud admin UI, select Applications > + Add Application, and create a new Web client with the following settings:

    Client ID

    myClient

    Client Secret

    forgerock

  2. Add the following settings in the client profile and save your work:

    Sign-in URLs

    https://www.example.com:443/callback

    Scopes

    openid
    profile

  3. Override OAuth 2.0 provider settings for this client.

    In the AM admin UI, 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

    OIDC Claims Plugin Type

    SCRIPTED

    OIDC Claims Script

    Demo access token modification

End user

The end user profile holds the values for the custom attributes referenced in your script.

  1. Create the end user account.

    In the Identity Cloud admin UI, select Identities > Manage > Alpha Realm - Users > + New Alpha Realm - User and fill the required fields.

    Record the username and password.

  2. Update the following settings in the new end user profile and save your work:

    Generic Unindexed String 1

    Custom string

    Generic Unindexed Multivalue 1

    custom
    value

    The script takes custom claim values from the AM attributes fr-attr-str1 and fr-attr-multi1. As described in User identity attributes and properties reference, the Identity Cloud admin UI labels these Generic Unindexed String 1 and Generic Unindexed Multivalue 1.

  3. Display the Raw JSON for the end user profile.

    Find the following settings in the JSON:

    {
      "frUnindexedString1": "Custom string",
      "frUnindexedMultivalued1": [
        "custom",
        "value"
      ]
    }

    Notice the AM attributes fr-attr-str1 and fr-attr-multi1 map to frUnindexedString1 and frUnindexedMultivalued1 in the JSON representation.

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 end user authenticates to obtain an SSO token.

  • The relying party (client) relies on Implied Consent being enabled (default) in the Identity Cloud admin UI under Applications > Client ID > Advanced settings > Authentication. It assumes the end user grants user info access to the relying party.

  • The relying party requests the authorization code and exchanges it for an ID token.

  • The relying party requests user info.

Follow these steps:

  1. Authenticate as the end user:

    curl \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'X-OpenAM-Username: <end-user-username>' \
    --header 'X-OpenAM-Password: <end-user-password>' \
    --header 'Accept-API-Version: resource=2.0, protocol=1.0' \
    'https://<tenant-env-fqdn>/am/json/realms/root/realms/alpha/authenticate'
    {"tokenId":"<end-user-tokenId>","successUrl":"/enduser/?realm=/alpha","realm":"/alpha"}
  2. Request the authorization code:

    curl \
    --dump-header - \
    --request POST \
    --Cookie '<session-cookie-name>=<end-user-tokenId>' \
    --data 'scope=openid profile' \
    --data 'response_type=code' \
    --data 'client_id=myClient' \
    --data 'csrf=<end-user-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…​
    …​
  3. Exchange the authorization code for an ID token:

    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": "h7h2LvM10mI_ABqwb1pzUzLt8NE",
      "refresh_token": "CK0f2_rBjKbhP0bjFnOVmN6BLD0",
      "scope": "openid profile",
      "id_token": "…​",
      "token_type": "Bearer",
      "expires_in": 3599
    }
  4. Display the claims in the ID token.

    You can use the jq command to display the values. In the following command, <IDToken> is the single-line JSON response object from the previous step:

    jq -R 'split(".") | .[1] | @base64d | fromjson' <<< '<IDToken>'
    {
      "at_hash": "_0Uie6DRQNgxqiSFa4EIDg",
      "sub": "014c54bd-6078-4639-8316-8ce0e7746fa4",
      "auditTrackingId": "b187bfdc-c0ff-4942-b4be-34a8c7134c40-3099380",
      "subname": "014c54bd-6078-4639-8316-8ce0e7746fa4",
      "iss": "https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha",
      "tokenName": "id_token",
      "given_name": "Test",
      "custom_string": "Custom string",
      "sid": "f1ChiEDjsYqYc/ML20bm4QZ9kQvmbIJmD+hZwkRdfOo=",
      "aud": "myClient",
      "c_hash": "j0ry4449CY9GonHxNEgC4A",
      "acr": "0",
      "org.forgerock.openidconnect.ops": "5NkCJhSacAzRsdELBgRJvbpuVMk",
      "s_hash": "bKE9UspwyIPg8LsQHkJaiQ",
      "custom_multivalue": [
        "value",
        "custom"
      ],
      "azp": "myClient",
      "auth_time": 1670316296,
      "name": "Test User",
      "realm": "/alpha",
      "exp": 1670319945,
      "tokenType": "JWTToken",
      "iat": 1670316345,
      "family_name": "User"
    }

    The script included "custom_string": "Custom string" and "custom_multivalue": ["value", "custom"].

  5. Make a request for user info:

    curl \
    --request POST \
    --header 'Authorization: Bearer dvZ3qHCBghiDvW1tu4Z-I6K3ogY' \
    'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/userinfo'
    {
      "name": "Test User",
      "family_name": "User",
      "given_name": "Test",
      "custom_string": "Custom string",
      "custom_multivalue": ["value", "custom"],
      "sub": "014c54bd-6078-4639-8316-8ce0e7746fa4",
      "subname": "014c54bd-6078-4639-8316-8ce0e7746fa4"
    }

    The script included the custom claims.

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:

  • In the AM admin UI, select Realms > realm > Services > OAuth2 Provider, switch to the Plugins tab, edit the OIDC Claims Script, and save your work.

  • In the Identity Cloud admin UI, select Scripts > Auth Scripts > Realm Name endUserUIClient OIDC Claims Script, and replace the script content with your validated script.

Available objects

AM injects the following objects into the execution context of a user info claims script:

Binding Information

claims

An object (map) of the default OpenID Connect 1.0 claims AM provides.

The keys are the claim strings. The values are the claim value objects.

claimLocales

An array of string values from the claims_locales parameter.

For details, refer to Claims Languages and Scripts in the OpenID Connect Core 1.0 specification.

claimObjects

The default OpenID Connect 1.0 claims AM provides.

An array of claim objects.

clientProperties

A read-only object (map) of the following client properties. This is present if AM identified the client specified in the request.

allowedGrantTypes

List of the grant types allowed for the client. For details, refer to the Javadoc for GrantType.

allowedResponseTypes

The list of the allowed response types for the client.

allowedScopes

The list of the allowed scopes for the client.

clientId

The client’s URI for the request locale.

customProperties

A map of any custom properties added to the client.

These properties can include lists or maps as sub-maps. For example, the script includes customMap[Key1]=Value1 as customMap > Key1 > Value1 in the object.

To add custom properties to a client, use the AM admin UI. Go to OAuth 2.0 > Clients > Client ID > Advanced, and update the Custom Properties field.

Scripts access the custom properties in the following way:

var customProperties = clientProperties.get("customProperties");
var property = customProperties.get("myProperty");

httpClient

An HTTP client for making external HTTP requests.

identity

A platform identity AM can access.

For details, refer to AMIdentity.

logger

Write a message to the AM debug log. Always present in all extension scripts.

In Identity Cloud, this corresponds to the am-core log source.

The logger identifier takes the form scripts.script-type.script-id.

For details, refer to Debug.

requestedClaims

An object (map) of requested claims. This is empty unless the request includes the claims query string parameter and AM is configured to support its use.

To configure AM in the AM admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect. Enable Enable "claims_parameter_supported" and save your change.

For details about the claims query string parameter, refer to Requesting Claims using the "claims" Request Parameter in the OpenID Connect Core 1.0 specification.

requestedTypedClaims

An array of the requested claims objects. This is empty unless the request includes claims.

A claim with a single value means the script should return only that value.

requestProperties

A read-only object (map) of the following request properties.

requestUri

The URI as a string.

realm

The realm as a string.

requestParams

A map of request parameters and posted data, where each value is an array of parameters.

To mitigate the risk of reflection-type attacks, use OWASP best practices when handling these parameters. Refer to Unsafe use of Reflection.

scopes

The set of scope strings in the client request.

scriptName

The display name of the script.

session

The user’s session object.

For details, refer to SSOToken.

Copyright © 2010-2023 ForgeRock, all rights reserved.