Adding Authentication Requirements to ID Tokens
Relying parties may require end users to satisfy different rules or conditions when authenticating to the provider. Consider the case of a financial services provider. While authenticating with username and password may be acceptable to create an account, accessing the end user's bank account details may require multi-factor authentication.
By specifying an authentication context reference (acr) or an authentication module reference (amr) claim in the request, relying parties can require that AM authenticate users using specific chains, modules, or trees.
The following sections show how AM implements both claims, and how to configure AM to honor them:
The Authentication Context Class Reference (acr) Claim
In the OpenID Connect specification, the acr
claim identifies a set of rules the user must satisfy when authenticating to the OpenID provider. For example, a chain or tree configured in AM.
To avoid exposing the name of authentication trees or chains, AM implements a map that consists of a key (the value that is included in the acr
claim) and the name of the authentication tree or chain.
The specification indicates that the acr
claim is a list of authentication contexts; AM honors the first value in the list for which it has a valid mapping. For example, if the relying party requests a list of acr values such as acr-1 acr-2 acr-3
and only acr-2
and acr-3
are mapped, AM will always choose acr-2
to authenticate the end user.
The acr
claim is optional and therefore is not added to ID tokens by default, but you can request AM to include it by specifying it as a voluntary or essential claim:
Request voluntary acr
claims when the fact that the user has authenticated to a specific chain or tree would improve the user experience in the OpenID Connect flow, but it is not a requisite.
You can request voluntary acr
claims in the following ways:
Specifying the authentication chains or trees in the
acr_values
parameter when requesting an ID token to the/oauth2/authorize
endpoint.Specifying the authentication chains or trees in JSON format in the
claims
parameter when requesting an ID token to the/oauth2/authorize
endpoint.
If the end user is already authenticated to the first value on the list for which AM has a mapping, AM does not force the user to reauthenticate. If they are not already authenticated, or if they are authenticated to any other tree or chain on the list, AM uses the first value for which it has a valid mapping to authenticate them.
Consider an example where the relying party requests a list of acr values, such as acr-1 acr-2 acr-3
, and AM only has acr-2
and acr-3
mapped:
AM will not force the end user to reauthenticate if they are already authenticated to
acr-2
(which is the first value in the list for which AM has a mapping).AM will force the end user to reauthenticate to
acr-2
in the following cases:If the end user has authenticated to
acr-3
.If the end user has authenticated to any other tree or chain.
If the end user has not yet authenticated.
If the user reauthenticates to a tree, AM destroys the original session and provides them with a new one that reflects the new authentication journey.
If the user reauthenticates to a chain, AM updates the original session to reflect the new authentication journey.
If the relying party requests authentication chains or trees that are not mapped in AM as valid acr values, AM continues the grant flow. The resulting ID token will contain an acr
claim with the following values:
0 (zero), if the client authenticated to AM using a chain or tree that is not mapped to an acr value.
acr_key_string, if the client authenticated to AM using a chain or tree that is mapped to an acr value.
If the end user authenticated to more than one chain or tree, AM will use the last chain or tree, provided it is mapped to an acr value.
Request essential acr
claims when the user must authenticate to a specific chain or tree to complete an OpenID Connect flow.
To request essential acr
claims, specify the required authentication chains or trees in JSON format in the claims
parameter when requesting an ID token to the /oauth2/authorize
endpoint.
AM will always force the end user to authenticate to the first value in the list for which AM has a mapping, even if the end user already authenticated using the same chain or tree.
Consider an example where the relying party requests a list of acr values, such as acr-1 acr-2 acr-3
, and AM only has acr-2
and acr-3
mapped:
AM will force the end user to authenticate to acr-2
in the following cases:
If the end user has authenticated to either
acr-2
oracr-3
.If the end user has authenticated to any other chain or tree.
If the end user is not authenticated.
If the user reauthenticates to a tree, AM destroys the original session and provides them with a new one that reflects the new authentication journey.
If the user reauthenticates to a chain, AM updates the original session to reflect the new authentication journey.
This mechanism can be used to perform step-up authentication, but AM does not consider if, for example, the authentication level of the current session is higher than the one achievable with the requested tree or chain.
If the relying party requests authentication chains or trees that are not mapped in AM as valid acr values, AM returns an error and redirects to the redirect_uri
value, if available.
Perform the steps in the following procedure to configure AM to honor acr
claims:
In the AM console, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect.
(Optional) To request
acr
claims using theclaims
parameter, enable "claims_parameter_supported".In the OpenID Connect acr_values to Auth Chain Mapping box, map an identifier (the key in the map) to an authentication chain or tree. For example:
The identifier is the string that AM will add in the
acr
claim.Save your changes.
(Optional) In the Default ACR values field, specify the identifiers of the authentication trees or chains AM should use to authenticate end users when acr values are not specified in the request. AM treats acr values specified in this field as voluntary claims.
Acr values specified in the request will override the default values.
If a request does not specify acr values and the Default ACR values field is empty, AM authenticates the end user with the default authentication chain or tree defined for the realm where the OAuth 2.0 provider is configured.
Tip
Query the
/oauth2/.well-known/openid-configuration
endpoint to determine the acr values supported by the OpenID provider. Mapped acr values are returned in theacr_values_supported
object.Save your changes.
(Optional) Review the "Requesting acr Claims Example".
This example assumes the following configuration:
An authentication tree called
Example
is configured in AM. For more information, see "Configuring Authentication Trees".The
Example
tree is mapped to theexample_tree
identifier in the acr_value map of the OAuth 2.0 provider. For more information, see "To Configure AM for the acr Claim".A public client called
myClient
is registered in AM with the following configuration:Scopes:
openid profile
Response Types:
token id_token
Grant Types:
Implicit
AM is configured as an OAuth 2.0/OpenID Provider.
Perform the following steps to request acr claims:
Log in to AM, for example, as the
demo
user. Ensure you are not using theExample
tree to log in, and note the value of theiplanetDirectoryPro
cookie.In a new tab of the same browser, request an ID token using, for example, the "Implicit Grant" flow. Perform one of the following steps:
Request voluntary claims with the
acr_values
parameter. For example:https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize? \ client_id=myClient \ &response_type=id_token \ &scope=openid%20profile \ &redirect_uri=https://www.example.com/callback \ &acr_values=example_chain%20example_tree \ &nonce=abc123 \ &prompt=login \ &state=123abc
Note that the URL is split for readability purposes and that the
prompt=login
parameter has been added. In most cases, this parameter is not required with the current implementation ofacr
claims, but it is recommended to add it for compliance with the specification when you need to force the user to re-authenticate.For information, see the prompt parameter.
Request voluntary claims with the
claims
parameter.The
claims
parameter expects a JSON object, such as:{"id_token":{"acr":{"values":["example_chain","example_tree"]}}}
For example:
https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize? \ client_id=myClient \ &response_type=id_token \ &scope=openid%20profile \ &redirect_uri=https://www.example.com/callback \ &nonce=abc123 \ &state=123abc \ &prompt=login \ &claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22values%22%3A%5B%22example_chain%22%2C%22example_tree%22%5D%7D%7D%7D
Note that the URL is split for readability purposes, and that the JSON value of the
claims
parameter is URL encoded.Request essential claims with the
claims
parameter.The
claims
parameter expects a JSON object, such as:{"id_token":{"acr":{"essential":true,"values":["example_chain","example_tree"]}}}
If
"essential":true
is not included in the JSON, AM assumes the acr request is voluntary.For example:
https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize? \ client_id=myClient \ &response_type=id_token \ &scope=openid%20profile \ &redirect_uri=https://www.example.com/callback \ &nonce=abc123 \ &state=123abc \ &prompt=login \ &claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22essential%22%3Atrue%2C%22values%22%3A%5B%22example_chain%22%2C%22example_tree%22%5D%7D%7D%7D
Note that the URL is split for readability purposes, and that the JSON value of the
claims
parameter is URL encoded.
AM redirects to the Example tree. Note that the new URL contains the following parameters:
authIndexValue
, the value of which is theExample
tree.goto
, the value of which is the URL the UI will use to return to the authorization endpoint once the authentication flow has finished.acr_sig
, the value of which is a unique string that identifies this particularacr
request.
Log in again as the
demo
user. Note that the value of theiplanetDirectoryPro
cookie changes to reflect the new session.AM redirects back to the authorization endpoint, and shows you the OAuth 2.0 consent page. Grant consent by selecting
Allow
. AM redirects you now to the URI specified by theredirect_uri
parameter with an ID token in the fragment.Decode the ID token. It contains the
acr
claim with the value ofexample_tree
, which the identifier mapped to theExample
tree in the acr_value map of the OAuth 2.0 provider:{ "at_hash": "3WHa52upb5ihwWVDC8a-Tw", "sub": "demo", "auditTrackingId": "fe330f16-2115-45fe-ae04-f68a9fc2ef92-65191", "iss": "https://openam.example.com:8443/openam/oauth2", "tokenName": "id_token", "nonce": "abc123", "sid": "I0GdWDfy1qhahDl1PpEA0v5LDspul+qW70biBhetUCk=", "aud": "myClient", "acr": "example_tree", "org.forgerock.openidconnect.ops": "7r1RiXbjWp1QBjJ8Uys4Ob8cwxY", "azp": "myClient", "auth_time": 1554724614, "realm": "/alpha", "exp": 1554728218, "tokenType": "JWTToken", "iat": 1554724618 }
The Authentication Method Reference (amr) Claim
In the OpenID Connect specification, the amr
claim identifies a family of authentication methods, such as a one-time password or multi-factor authentication.
In AM, you can map authentication modules to specific values that the relying party understands. For example, you could map an amr value called PWD
to the LDAP module.
Unlike acr
claims, relying parties do not request amr
claims. As long as authentication modules are mapped to amr values, and provided that end users log in using one of the mapped modules, AM will return the amr
claim in the ID token.
Since authentication nodes are not used on their own but as part of a tree context, you cannot map amr values to specific authentication nodes. However, you can map an AuthType
session property to an amr value using the "Set Session Properties Node". AM will add the configured amr claim to the ID token, provided the user's journey on the tree goes through the node.
The following is an example of a decoded ID token that contains both acr
and amr
claims:
{ "at_hash": "kP7U-po4xla0OYqJ60p72Q", "sub": "demo", "auditTrackingId": "ac8ecadc-140f-48a0-b3ec-ccd02d6f9c3d-183361", "amr": [ "PWD" ], "iss": "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha", "tokenName": "id_token", "nonce": "abc123", "sid": "I0GdWDfy1qhahDl1PpEA0v5LDspul+qW70biBhetUCk=", "aud": "myClient", "acr": "0", "org.forgerock.openidconnect.ops": "hM7F00xw0kzb7os_S9KdmDphosY", "azp": "myClient", "auth_time": 1554889732, "realm": "/alpha", "exp": 1554893403, "tokenType": "JWTToken", "iat": 1554889803 }
In this example, the end user logged in with an authentication chain or tree that is not mapped to an acr value. Therefore, AM returned "acr": "0"
. However, the relying party at least knows the user logged in with an authentication method of the family PWD
. The relying party can use this knowledge to take additional actions, such as request the end user to reauthenticate using a particular chain or tree.
See the following procedures to map amr values:
In the AM console, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect.
In the OpenID Connect id_token amr Values to Auth Module Mappings box, map an identifier (the key in the map) to any authentication module. The authentication module you use is not important; AM will only use its name to map the amr, and it will not show in the ID token.
Save your changes.
Create an authentication tree containing the "Set Session Properties Node".
On the Set Session Properties node, configure a key called
AuthType
. As its value, set the name of the authentication module you configured with the amr mapping. For example,LDAP
.Tip
To reference multiple authentication modules, separate amr values with
|
. For example, if both the LDAP and the DataStore modules are mapped to amr values, set theAuthType
key to the valueLDAP|DataStore
.Go to Realms > Realm Name > Services, and add a Session Property Whitelist service if one is not already available.
On the Whitelisted Session Property Names field, add the
AuthType
key. This will ensure that the property can be read, edited, or deleted, from a session.Save your changes.
In the AM console, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect.
In the OpenID Connect id_token amr Values to Auth Module Mappings box, map an identifier (the key in the map) to an authentication module.
Save your changes.