OIDC user info claims
This plugin extension point is invoked when issuing an ID token or during a
request to the /userinfo
OIDC endpoint. Use this script to retrieve
claim values based on an issued access token.
- Default script
-
To view the default script, including the available script properties, refer to oidc-claims-extension.groovy.
To view or modify the default script in the AM admin UI, go to Realms > Realm Name > Scripts and select OIDC Claims Script.
- Java interface
- Java sample
Show Sample Code
/*
* Copyright 2021-2022 ForgeRock AS. All Rights Reserved
*
* Use of this code requires a commercial software license with ForgeRock AS.
* or with one of its affiliates. All use shall be exclusively subject
* to such license between the licensee and ForgeRock AS.
*/
package org.forgerock.openam.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.forgerock.oauth2.core.AccessToken;
import org.forgerock.oauth2.core.ClientRegistration;
import org.forgerock.oauth2.core.OAuth2Request;
import org.forgerock.oauth2.core.UserInfoClaims;
import org.forgerock.oauth2.core.plugins.UserInfoClaimsPlugin;
/**
* Custom implementation of the User Info Claims
* plugin interface {@link org.forgerock.oauth2.core.plugins.UserInfoClaimsPlugin}
*
* <li>
* The {@code getUserInfo} method
* populates scope values and sets the resource owner ID to return.
* </li>
*
*/
public class CustomUserInfoClaimsPlugin implements UserInfoClaimsPlugin {
@Override
public UserInfoClaims getUserInfo(ClientRegistration clientRegistration, AccessToken token, OAuth2Request request) {
Map<String, Object> response = mapScopes(token);
response.put("sub", token.getResourceOwnerId());
UserInfoClaims userInfoClaims = new UserInfoClaims(response, null);
return userInfoClaims;
}
/**
* Set read and write permissions according to scope.
*
* @param token The access token presented for validation.
* @return The map of read and write permissions,
* with permissions set to {@code true} or {@code false},
* as appropriate.
*/
private Map<String, Object> mapScopes(AccessToken token) {
Set<String> scopes = token.getScope();
Map<String, Object> map = new HashMap<String, Object>();
final String[] permissions = {"read", "write"};
for (String scope : permissions) {
if (scopes.contains(scope)) {
map.put(scope, true);
} else {
map.put(scope, false);
}
}
return map;
}
}
Example user info claims plugin
Complete the following steps to implement an example user info claims script that adds a custom claim to the profile scope:
Configure the user info claims script
This task describes how to modify the default script to map a custom claim. To create a new script instead, refer to the steps described in Manage scripts (UI), and reference the new script name when you configure the provider.
-
In the AM admin UI, go to Realms > Realm Name > Scripts, and click OIDC Claims Script.
-
In the Script field:
-
Add a new claim to the script. As a simple example, insert
myTestName
after thename
claim in theclaimAttributes
section, as follows:claimAttributes = [ "email": userProfileClaimResolver.curry("mail"), ... "name": userProfileClaimResolver.curry("cn"), "myTestName": userProfileClaimResolver.curry("cn") ]
-
Add the new claim to the
profile
scope in the claims map:scopeClaimsMap = [ "email": [ "email" ], ... "profile": [ "given_name", "zoneinfo", "family_name", "locale", "name", "myTestName" ]
For a more complex example of customizing the user info claims script, refer to How do I add a session property claim to the OIDC Claims Script? in the Knowledge Base.
You can also use the script to override the claims included in an ID token. For example, you can add a
post_logout_url
claim that redirects a user’s browser to the URL specified in the claim, when that user signs out of an End User UI.The following example adds a final item to
claimAttributes
to returnhttps://forgerock.com
as thepost_logout_url
claim. Adapt the method used to return the appropriate URL for your application:+
claimAttributes = [ //..., "post_logout_url": { claim, identity -> return [(claim.getName()): "https://forgerock.com"] } ]
Add the claim for the
fr:idm:*
scope as a final item in thescopeClaimsMap
:+
scopeClaimsMap = [ //..., "fr:idm:*": [ "post_logout_url" ] ]
For more information, refer to How do I override claims in the OIDC ID token in PingAM? in the Knowledge Base.
-
-
Save your changes.
The default user info claims script is now amended to retrieve a custom claim for the profile
scope.
This script accesses the /userinfo endpoint and retrieves claims from the profile scope only. To retrieve
all scopes and claims, use the /introspect endpoint.
|
Configure AM to use the user info claims script
Perform this task to set up an OAuth2 provider to use your custom script.
-
Log in to the AM admin UI as an administrator.
For example,
amAdmin
. -
Configure the provider to ensure the following properties are set:
-
OIDC Claims Plugin Type to
SCRIPTED
. -
OIDC Script to
OIDC Claims Script
.
If you created a new script rather than editing the default, you must reference the new script name here.
-
-
Save your changes.
Create an OAuth2 client for authorization
Create a public OAuth 2.0 client to use in the authorization request.
-
In the AM admin UI, go to Realms > Realm Name > Applications > OAuth 2.0 > Clients, and click Add Client.
-
Enter the following values:
-
Client ID:
myClient
-
Client secret:
forgerock
-
Redirection URIs:
https://www.example.com:443/callback
-
Scope(s):
openid profile
-
-
Click Create.
-
In the Core tab, set Client type to
Public
. -
In the Advanced tab, set the following values:
-
Grant Types:
Implicit
-
Token Endpoint Authentication Method:
none
-
Grant Types:
token id_token
-
AM is now prepared for you to try the sample user info claims script.
Try the custom user info claims plugin script
To try your custom script, use the Implicit grant flow as demonstrated in the following steps.
-
Log in to AM as the
demo
user, for example:$ curl \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: demo" \ --header "X-OpenAM-Password: Ch4ng31t" \ --header "Accept-API-Version: resource=2.0, protocol=1.0" \ 'https://openam.example.com:8443/openam/json/realms/root/realms/alpha/authenticate' { "tokenId":"AQIC5wM…TU3OQ*", "successUrl":"/openam/console", "realm":"/alpha" }
Note the SSO token value returned as
tokenId
in the output. -
Invoke the authorization server’s /oauth2/authorize endpoint specifying the SSO token value in a cookie, and the following parameters as a minimum:
-
client_id=
myClient
-
response_type=
token id_token
-
scope=
openid profile
-
nonce=your nonce value
-
redirect_uri=
https://www.example.com:443/callback
-
decision=
allow
-
csrf=SSO-token
For example:
$ curl --dump-header - \ --Cookie "iPlanetDirectoryPro=AQIC5wM…TU3OQ*" \ --request POST \ --data "client_id=myClient" \ --data "response_type=token id_token" \ --data "scope=openid profile" \ --data "state=123abc" \ --data "nonce=abc123" \ --data "decision=allow" \ --data "csrf=AQIC5wM…TU3OQ*" \ --data "redirect_uri=https://www.example.com:443/callback" \ "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize"
If the authorization server successfully authenticates the user, note the value of the access token appended to the redirection URI in the response.
-
-
Call the /oauth2/userinfo endpoint to inspect the custom claim values, including the access token obtained from the previous request.
For example:
$ curl --request GET --header "Authorization: Bearer az91IvnIQ-uP3Eqw5QqaXXY_DCo" \ "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/userinfo" { "given_name":"Demo First Name", "family_name":"Demo Last Name", "name":"demo", "myTestName":"demo", "sub":"(usr!demo)", "subname":"demo" }
Verify that the response contains the custom claim added by the script (
myTestName
in this example).
OIDC user info claims scripting API
The following properties are available to user info claims scripts.
Binding | Information | ||
---|---|---|---|
|
A map of the claims the server provides by default. For example:
|
||
|
An array of string values from the For details, refer to Claims Languages and Scripts in the OpenID Connect Core 1.0 specification. |
||
|
The default OpenID Connect 1.0 claims provided by AM. |
||
|
A read-only map of the following client properties. Only present if AM identified the client specified in the request.
|
||
|
An HTTP client for making external HTTP requests. |
||
|
Represents an identity that AM can access. For details, refer to AMIdentity. |
||
The logger instance for the script. Logger names use the format Refer to Debug logging. |
|||
|
A map of requested claims.
This is empty unless the request includes the 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 Example:
|
||
|
A list of the requested claims objects.
This is empty unless the request includes the A claim with a single value means the script should return only that value. |
||
|
A read-only map of the following request properties.
|
||
|
The set of scope strings in the client request. |
||
|
The display name of the script. |
||
|
The user’s session object. For details, refer to SSOToken. |