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 authentication mechanisms.

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 mechanism configured in AM.

To avoid exposing the name of authentication mechanism, AM implements a map that consists of a key (the value that is included in the acr claim) and the name of the authentication mechanism.

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:

Voluntary Claim

Request voluntary acr claims when the fact that the user has authenticated to a specific mechanism 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 mechanism in the acr_values parameter when requesting an ID token to the /oauth2/authorize endpoint.

  • Specifying the authentication mechanisms 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 mechanism 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 mechanism.

    • 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 relying party requests authentication mechanisms 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 mechanism that is not mapped to an acr value.

  • acr_key_string, if the client authenticated to AM using a mechanism that is mapped to an acr value.

    If the end user authenticated to more than one mechanism, AM will use the last mechanism, provided it is mapped to an acr value.

Essential Claim

Request essential acr claims when the user must authenticate to a specific mechanism to complete an OpenID Connect flow.

To request essential acr claims, specify the required authentication mechanisms 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 mechanism.

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 or acr-3.

  • If the end user has authenticated to any other mechanism.

  • 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.

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 mechanism.

If the relying party requests authentication mechanisms 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:

To Configure AM for the acr Claim

  1. In the AM Admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect.

  2. To request acr claims using the claims parameter, enable "claims_parameter_supported".

  3. In the OpenID Connect acr_values to Auth Chain Mapping box, map an identifier (the key in the map) to an authentication mechanism.

    For example:

    oidc-acr-values

    The identifier is the string that AM will add in the acr claim.

  4. Save your changes.

  5. In the Default ACR values field, specify the identifiers of the authentication mechanisms 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 mechanism defined for the realm where the OAuth 2.0 provider is configured.

    Query the /oauth2/.well-known/openid-configuration endpoint to determine the acr values supported by the OpenID provider. Mapped acr values are returned in the acr_values_supported object.

  6. Save your changes.

  7. Review the Requesting acr Claims Example.

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 the example_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:

  1. Log in to AM, for example, as the demo user.

    Ensure you are not using the Example tree to log in, and note the value of the iplanetDirectoryPro cookie.

  2. 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:

    1. Request voluntary claims with the acr_values parameter. For example:

      https://tenant-name.forgeblocks.com/am/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 of acr claims, but it is recommended to add it for compliance with the specification when you need to force the user to re-authenticate.

    2. 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://tenant-name.forgeblocks.com/am/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.

    3. 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://tenant-name.forgeblocks.com/am/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 the Example 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 particular acr request.

  3. Log in again as the demo user.

    Note that the value of the iplanetDirectoryPro 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 the redirect_uri parameter with an ID token in the fragment.

  4. Decode the ID token.

    It contains the acr claim with the value of example_tree, which the identifier mapped to the Example 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://tenant-name.forgeblocks.com/am/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.

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://tenant-name.forgeblocks.com/am/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 mechanism 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 mechanism.

To Use a Set Session Properties Node to Map an amr Value

  1. In the AM Admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced OpenID Connect.

  2. Save your changes.

  3. Create an authentication tree containing the Set Session Properties Node.

  4. 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.

    Example: Configuring the AuthType Session Property
    amr-set-session-properties
  5. Go to Realms > Realm Name > Services, and add a Session Property Whitelist service if one is not already available.

  6. 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.