OAuth 2.0 in AM/OpenAM

This book provides information on OAuth 2.0 in AM/OpenAM including OIDC and UMA, administering access tokens via REST and and known issues (with solutions).


What federation standards does AM/OpenAM support?

The purpose of this article is to provide information on the supported federation standards in AM/OpenAM.

Overview

This article provides information on the following federation standards:

OAuth 2.0 support

Grant Flows AM 6.5.2 AM 6.5.1 AM 6.5 AM 6 AM 5.5 AM 5/5.1 OpenAM 13.x OpenAM 12.x Documentation Reference
Authorization Code Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 6749)
Authorization Code with PKCE Yes Yes Yes -- -- -- -- -- OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 6749, RFC 7636)
Implicit Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 6749)
Client Credentials Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 6749)
Resource Owner Password Credentials  Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 6749)
Device Flow Yes Yes Yes Yes Yes Yes Yes --

OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows

(Internet-Draft: OAuth 2.0 Device Flow for Browserless and Input Constrained Devices)

Device Flow with PKCE  Yes Yes Yes -- -- -- -- --

OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows

(Internet-Draft: OAuth 2.0 Device Flow for Browserless and Input Constrained Devices, RFC 7636)

SAML v2.0 Profile for Authorization Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows (RFC 7522)
Client Type                  
Confidential Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › /json/realm-config/agents/OAuth2Client
Public Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › /json/realm-config/agents/OAuth2Client
Credential Type                  
Access token Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › AM as the OAuth 2.0 Authorization Server
Refresh token Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › AM as the OAuth 2.0 Authorization Server
Additional Features                  
Bearer Token Usage Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Using Your Own Client and Resource Server (RFC 6750)
Token Revocation Yes Yes Yes Yes Yes Yes Yes * -- Reference › Supported Standards (RFC 7009)
OAuth 2.0 Token Introspection Yes Yes Yes Yes Yes Yes Yes * -- Reference › Supported Standards (RFC 7662)
JSON Web Token (JWT) Yes Yes Yes Yes  Yes Yes Yes -- Reference › Supported Standards (RFC 7519)
JSON Web Token (JWT) Profile Yes Yes Yes Yes Yes Yes Yes Yes OAuth 2.0 Guide › Authenticating Clients Using JWT Profiles (RFC 7523)
JWT Profile for OAuth 2.0 Authorization Grant Yes -- -- -- -- -- -- -- OAuth 2.0 Guide › JWT Profile for OAuth 2.0 Authorization Grant (RFC 7523)
OAuth 2.0 Mutual TLS (mTLS) Yes Yes -- -- -- -- -- --

OAuth 2.0 Guide › Authenticating Clients Using Mutual TLS

(Internet-Draft: OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens)

Proof-of-Possession Key Semantics for JWT Yes Yes Yes Yes Yes Yes -- -- Reference › Supported Standards (RFC 7800)
JSON Web Signature (JWS) Yes Yes Yes Yes Yes Yes Yes -- Reference › Supported Standards (RFC 7515)
JSON Web Key (JWK) Yes Yes Yes Yes Yes Yes Yes -- Reference › Supported Standards (RFC 7517)
JSON Web Algorithms (JWA) Yes Yes Yes Yes Yes Yes Yes -- Reference › Supported Standards (RFC 7518)
Dynamic Client Registration Yes Yes Yes Yes Yes -- -- -- OAuth 2.0 Guide › Dynamic Client Registration (RFC 7591)
Dynamic Client Registration Management Yes Yes -- -- -- -- -- -- OAuth 2.0 Guide › Dynamic Client Registration Management (RFC 7592)
Remote Consent Service Support Yes Yes Yes Yes Yes -- -- -- OAuth 2.0 Guide › OAuth 2.0 Remote Consent Service

* Supported as of OpenAM 13.5 

OpenID Connect 1.0 support

Specification AM 6.5.2 AM 6/6.5/6.5.1 AM 5.x OpenAM 13.x OpenAM 12.x * Documentation Reference
OpenID Connect Core 1.0 Yes Yes Yes Yes -- Reference › Supported Standards
OpenID Connect Client Initiated Backchannel Authentication Flow - Core 1.0 Yes -- -- -- -- Reference › Supported Standards
OpenID Connect Discovery 1.0 Yes Yes Yes Yes -- Reference › Supported Standards
OpenID Connect Dynamic Client Registration 1.0 Yes Yes Yes Yes -- Reference › Supported Standards
OpenID Connect Session Management 1.0 Yes Yes Yes Yes -- Reference › Supported Standards
OAuth 2.0 Multiple Response Type Encoding Practices Yes Yes Yes Yes -- Reference › Supported Standards
OAuth 2.0 Form Post Response Mode Yes Yes Yes Yes -- Reference › Supported Standards
OpenID Connect Basic Client Implementer's Guide 1.0 Yes Yes Yes Yes -- Reference › Supported Standards
OpenID Connect Implicit Client Implementer's Guide 1.0 Yes Yes Yes Yes -- Reference › Supported Standards

 * The OIDC specifications are partially supported in OpenAM 12.x but are not fully compliant.

UMA 2.0 support

Specification AM 6.x AM 5.5 AM 5/5.1 OpenAM 13.x OpenAM 12.x Documentation Reference
UMA 2.0 Grant for OAuth 2.0 Authorization Yes Yes -- -- -- Reference › Supported Standards
Federated Authorization for UMA 2.0 Yes Yes -- -- -- Reference › Supported Standards

UMA 1.x support

Specification AM 6.x AM 5.5 AM 5/5.1 OpenAM 13.x OpenAM 12.x Documentation Reference
User-Managed Access (UMA) Profile of OAuth 2.0 -- -- Yes Yes -- Reference › Supported Standards
OAuth 2.0 Resource Set Registration -- -- Yes Yes -- Reference › Supported Standards

SAML 2.0 support

Profile AM 6.x AM 5.x OpenAM 13.x OpenAM 12.x Documentation Reference
Web Browser SSO Profile Yes Yes Yes Yes  
Enhanced Client or Proxy (ECP) Profile Yes Yes Yes Yes SAML v2.0 Guide › Configuring for the ECP Profile
Identity Provider Discovery Profile Yes Yes Yes Yes SAML v2.0 Guide › Deploying the Identity Provider Discovery Service
Single Logout Profile Yes Yes Yes Yes SAML v2.0 Guide › Implementing SAML v2.0 Single Sign-On and Single Logout
Name Identifier Management Profile Yes Yes Yes Yes SAML v2.0 Guide › Changing Federation of Persistently Linked Accounts
Artifact Resolution Profile Yes Yes Yes Yes SAML v2.0 Guide › Services
Assertion Query/Request Profile Yes Yes Yes Yes SAML v2.0 Guide › Assertion Cache
Name Identifier Mapping Profile Yes Yes Yes Yes SAML v2.0 Guide › NameID Mapping
SAML Attribute Profiles
  • Basic Attribute Profile
  • X.500/LDAP Attribute Profile
  • UUID Attribute Profile
  • DCE PAC Attribute Profile
  • XACML Attribute Profile
Yes Yes Yes Yes SAML v2.0 Guide › Attribute Mapper
Binding          
SAML SOAP Binding Yes Yes Yes Yes Reference › Console Service JSP Files
Reverse SOAP (PAOS) Binding Yes Yes Yes Yes SAML v2.0 Guide › Configuring for the ECP Profile
HTTP Redirect Binding Yes Yes Yes Yes SAML v2.0 Guide › JSP Pages for SSO and SLO
HTTP POST Binding Yes Yes Yes Yes SAML v2.0 Guide › JSP Pages for SSO and SLO
HTTP Artifact Binding Yes Yes Yes Yes SAML v2.0 Guide › JSP Pages for SSO and SLO
SAML URI Binding -- -- -- --  
Assertion Signature Algorithms          
rsa-sha1 Yes Yes Yes Yes Reference › Supported Standards
rsa-sha256 Yes Yes Yes Yes Reference › Supported Standards
rsa-sha384 Yes Yes Yes Yes Reference › Supported Standards
rsa-sha512 Yes Yes Yes Yes Reference › Supported Standards
Assertion Encryption Algorithms          
aes128-cbc Yes Yes Yes Yes Reference › Supported Standards
aes192-cbc Yes Yes Yes Yes Reference › Supported Standards
aes256-cbc Yes Yes Yes Yes Reference › Supported Standards
tripledes-cbc Yes Yes Yes Yes Reference › Supported Standards
QueryString Signature Algorithms *          
rsa-sha1 Yes Yes Yes Yes Reference › Supported Standards
rsa-sha256 Yes Yes Yes -- Reference › Supported Standards
rsa-sha384 Yes Yes Yes -- Reference › Supported Standards
rsa-sha512 Yes Yes Yes -- Reference › Supported Standards
dsa-sha1 Yes Yes Yes Yes Reference › Supported Standards
ecdsa-sha1 Yes Yes Yes -- Reference › Supported Standards
ecdsa-sha256 Yes Yes Yes -- Reference › Supported Standards
ecdsa-sha384 Yes Yes Yes -- Reference › Supported Standards
ecdsa-sha512 Yes Yes Yes -- Reference › Supported Standards

* Support for all the listed QueryString Signature Algorithms was introduced in OpenAM 12.0.3.

SAML 1.x support

Profile AM 6.x * AM 5.x OpenAM 13.x OpenAM 12.x Documentation Reference
IdP-initated SSO Browser Post Yes Yes Yes Yes SAML v1.x Guide › About SAML v1.x
IdP-initated SSO Browser Artifact Yes Yes Yes Yes SAML v1.x Guide › About SAML v1.x
Non-normative SP-initiated scenario (called “destination-first”) Yes Yes Yes Yes SAML v1.x Guide › About SAML v1.x

* SAML 1.x support is deprecated in AM 6.5 and will be removed in a future version. 

WS-Federation 1.1 support

Protocol AM 6.x AM 5.x OpenAM 13.5 OpenAM 13.0 OpenAM 12.x Documentation Reference
WS-Federation Passive Requestor Profile for SP-initiated SSO Yes Yes Yes Yes Yes How do I configure AM (All versions) or OpenAM 13.5.x as an Identity Provider for Microsoft Office 365 and Azure using WS-Federation?
WS-Federation Active Requestor Profile Yes Yes Yes  -- --  

Web Services Security support

Specification Namespace AM 6.x AM 5.x OpenAM 13.x OpenAM 12.x Documentation Reference
SOAP 1.1 Schema for the SOAP/1.1 envelope Yes Yes Yes Yes API Javadoc › Class SAMLConstants
SOAP 1.2 Schema defined in the SOAP Version 1.2 Part 1 specification Yes Yes Yes Yes API Javadoc › Class SAMLConstants
WS-Trust 2005 Web Services Trust Language (WS-Trust) -- -- -- Yes  
WS-Trust 1.3 WS-Trust 1.3 -- -- -- Yes  
WS-Trust 1.4 WS-Trust 1.4 Yes Yes Yes Yes Security Token Service Guide

See Also

FAQ: SAML federation in AM/OpenAM

FAQ: SAML certificate management in AM/OpenAM

How does AM/OpenAM (All versions) use account mapping to identify the end user from a SAML Assertion?

How do I know which binding to use for SAML2 federation in AM/OpenAM (All versions)?

How do I configure AM/OpenAM (All versions) to integrate with Microsoft Office 365 using SAML2?

How do I configure AM (All versions) or OpenAM 13.5.x as an Identity Provider for Microsoft Office 365 and Azure using WS-Federation?

How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

How do I request further information (such as client_id or uid) for an OAuth 2.0 access token in AM/OpenAM (All versions)?

FAQ: OAuth 2.0 in AM/OpenAM

SAML Federation in AM/OpenAM

OAuth 2.0 in AM/OpenAM

Reference › Supported Standards

Related Training

N/A

Related Issue Tracker IDs

N/A


How does OAuth 2.0 Saved Consent work in AM/OpenAM (All versions)?

The purpose of this article is to provide information on how OAuth 2.0 Saved Consent works in AM/OpenAM, including details about the relationship between the Saved Consent Attribute Name and scopes.

Overview

The scope attribute in the authorization request lists the scopes that specify what type of access has been granted by the user. When a user is presented with a consent page and selects "Save consent", an entry will be added to the user profile containing the requested scope. See OAuth 2.0 Guide › Managing OAuth 2.0 Consent for further information.

Saved consent attribute

When you configure the OAuth 2.0 Authorization Service, you should specify the Saved Consent Attribute Name (which is the profile attribute used for saving authorization consent decisions). See OAuth 2.0 Guide › Consent for further information.

When you first access the authorize endpoint, the consent page is shown and your consent will be saved in this attribute if you allow it:

  • If you make a subsequent request from the same client with the same scopes, you will not see the consent page again.
  • If you make a subsequent request from a different client and/or with different scopes, you will be prompted for consent again.

The way consent is handled has changed between versions as a result of OPENAM-8479 (OAuth2 Scriptable/policy-driven Scopes). In essence, consent for each scope is saved separately in AM 6 and later to give more flexibility, whereas consent was saved for the scope combination in pre-AM 6. This is explained in more detail with examples in the following sections:

Note

There is a known issue in AM 5.5.1 and 6: OPENAM-12997 (Consent for default scopes are not saved). This is fixed in AM 6.5.

Saved consents behavior in AM 6 and later

 A user's decision to save consent is specific to each scope in the authorization request and consent for each scope is saved separately. If subsequent requests contain a different scope combination, consent will not be required if the scopes within that combination can be found across multiple saved consents. If part of the scope cannot be found, consent is required.

Example

You have created a profile attribute called oAuth2SavedConsent and specified this in the Saved Consent Attribute Name field.

  • User.1 authorizes with scopes CONTACTS.READ,LOCATION.READ and chooses to save their consent. Consent for each scope (CONTACTS.READ and LOCATION.READ) is saved separately in the oAuth2SavedConsent attribute. 
  • User.1 makes another request with just the CONTACTS.READ scope; they are not prompted to save their consent because consent for this scope has already been saved.
  • User.1 then makes another request with scope EMAIL.READ; they are prompted to save their consent because this is a different scope.
  • User.1 makes a final request with scopes LOCATION.READ,EMAIL.READ; they are not prompted to save their consent because consent for these scopes has already been saved. 

At this point, requests with CONTACTS.READ, LOCATION.READ and/or EMAIL.READ scopes (and any combination of them) will not require consent as consent has already been saved for each of these scopes; however any further requests with different scopes will required a new consent to be saved.

Saved consents behavior in pre-AM 6

A user's decision to save consent is specific to the scope(s) in the authorization request and consent is saved for the scope combination presented. If subsequent requests contain a different scope combination, consent will not be required if the matching scope(s) are found in a saved consent entry. If part of the scope cannot be found, consent is required.

Example

You have created a profile attribute called oAuth2SavedConsent and specified this in the Saved Consent Attribute Name field.

  • User.1 authorizes with scopes CONTACTS.READ,LOCATION.READ and chooses to save their consent. Consent for this scope combination (CONTACTS.READ,LOCATION.READ) is saved in the oAuth2SavedConsent attribute. 
  • User.1 makes another request with just the CONTACTS.READ scope; they are prompted to save their consent because this is considered a different scope.
  • User.1 then makes another request with scopes CONTACTS.READ,LOCATION.READ; they are not prompted to save their consent this time because this consent has already been saved.

At this point, requests with either CONTACTS.READ,LOCATION.READ or CONTACTS.READ scopes will not require consent as consent has already been saved; however any further requests with different scopes will required a new consent to be saved.

See Also

FAQ: OAuth 2.0 in AM/OpenAM

How do I bypass the OAuth 2.0 Authorization Consent page in AM/OpenAM (All versions)?

OAuth 2.0 in AM/OpenAM

OAuth 2.0 Guide

Related Training

ForgeRock Access Management Core Concepts (AM-400)

Related Issue Tracker IDs

OPENAM-14683 (Update AM 6.5 Release Notes to document OAuth2 saved consent behaviour changes)

OPENAM-14633 (User is not prompted for consent when requesting different scopes to those previously requested and saved)

OPENAM-8479 (OAuth2 Scriptable/policy-driven Scopes)


How do I check that an OAuth 2.0 client can connect to AM/OpenAM (All versions)?

The purpose of this article is to provide information on checking that an OAuth 2.0 client or OIDC client can connect to AM/OpenAM. The results of the connectivity check serves various purposes, including: validating credentials are correct and verifying the client can authenticate to AM/OpenAM for determining access.

Checking that an OAuth 2.0 client can connect

Note

For the OAuth 2.0 client to be able to authenticate, agent must be listed as an Identity Type (Realms > [Realm Name] > Authentication > Settings > General > Identity Types). It is included by default, but if it missing, you will see the following response: { "code": 401, "reason": "Unauthorized", "message": "User Requires Profile to Login" } and should re-add it.

The following check validates the client credentials to prove that the client can connect to AM/OpenAM but does not create a session, this is done by simply validating the OAuth2 client and client secret. This method may be preferable to the alternative for testing, which involves generating an access token and then revoking it.

You can validate the client credentials using a REST call similar to this:

  • AM 5 and later:
    $ curl -X POST -H "X-OpenAM-Username: myOAuth2Client" -H "X-OpenAM-Password: clientPassword" -H "Content-Type: application/json" -H "Accept-API-Version: resource=2.1" http://host1.example.com:8080/openam/json/realms/root/authenticate?realm=/&noSession=true&authIndexType=module&authIndexValue=Application
    
  • Pre-AM 5:
    $ curl -X POST -H "X-OpenAM-Username: myOAuth2Client" -H "X-OpenAM-Password: clientPassword" -H "Content-Type: application/json" 
    http://host1.example.com:8080/openam/json/authenticate?realm=/&noSession=true&authIndexType=module&authIndexValue=Application
    

A successful response will look similar to this, where a session token is not created because of the noSession parameter:

{"message":"Authentication Successful","successUrl":"/openam/console","realm":"/"

Whereas an unsuccessful response is similar to this:

{"code":401,"reason":"Unauthorized","message":"Authentication Failed"}

See Also

How do I check if AM/OpenAM (All versions) is up and running?

How do I check that a Policy Agent (All versions) can connect to AM/OpenAM?

OAuth 2.0 in AM/OpenAM

OAuth 2.0 Guide

Related Training

N/A

Related Issue Tracker IDs

N/A


How do I improve OAuth 2.0 performance in OpenAM 13.0?

The purpose of this article is to provide information on improving OAuth 2.0 performance in OpenAM 13.0.

Improving OAuth 2.0 performance

In OpenAM 13.0, there is a known performance issue: OPENAM-8023 (OAuth2 load: contention at com.sun.identity.sm.ServiceConfigImpl.getInstance level (perf regression compared to AM12.0.2)). This issue is resolved in OpenAM 13.5. 

You can mitigate this issue in OpenAM 13.0 as follows:

  1. Create a completely empty file. For example, you can use the following command if you are using a Linux® or Unix® operating system:
    $ touch [filename]
  2. Run the following ssoadm commands against all realms where you are using OAuth2:
    $ ./ssoadm add-svc-realm -e [realmname] -s ScriptingService -u [adminID] -f [passwordfile] -D [emptyfile]
    $ ./ssoadm create-sub-cfg -e [realmname] -s ScriptingService -g scriptConfigurations -u [adminID] -f [passwordfile] -D [emptyfile] 
    
    replacing [realmname], [adminID], [passwordfile] and [emptyfile] with appropriate values.

See Also

N/A

Related Training

N/A

Related Issue Tracker IDs

OPENAM-8023 (OAuth2 load: contention at com.sun.identity.sm.ServiceConfigImpl.getInstance level (perf regression compared to AM12.0.2))


How do I bypass the OAuth 2.0 Authorization Consent page in AM/OpenAM (All versions)?

The purpose of this article is to provide information on bypassing the OAuth 2.0 Authorization Consent page in AM/OpenAM when you are using the Authorization Code Grant flow. There are other OAuth2 grant flows where bypassing consent is unnecessary because the OAuth2 spec does not require consent to be sought.

Bypassing the Authorization Consent page (AM, OpenAM 13.5)

Note

You can bypass the Authorization Consent page for (trusted) application-to-application or service-to-service interaction.

As of OpenAM 13.5, you can make the Authorization Consent page optional by enabling both of these options:

  • OAuth2 Provider - Allow Clients to Skip Consent option.
  • OAuth 2.0 Client (Agent) - Implied consent option.

See OAuth 2.0 Guide › Allowing Clients To Skip Consent for further information.

Bypassing the Authorization Consent page (Pre-OpenAM 13.5)

Note

You can bypass the Authorization Consent page for (trusted) application-to-application or service-to-service interaction.

Prior to OpenAM 13.5, you can choose to save user consent, so that the Authorization Consent page is only presented once. 

You can save user consent by setting the Saved Consent Attribute Name parameter with the name of the profile attribute you want OpenAM to use for saving authorization consent decisions. This should be a multi-valued attribute on the resource owner profile.

See: Administration Guide › Configuring the OAuth 2.0 Authorization Service for detailed instructions.

The salient points are:

  • Add a multi-valued string syntax profile attribute to your identity repository. OpenAM stores resource owners' consent to authorize client access in this profile attribute. On subsequent requests from the same client for the same scopes, the resource owner no longer sees the authorization page.
  • You are not likely to find a standard profile attribute for this. For evaluation purposes only, you might try an unused existing profile attribute, such as description.
  • When moving to production, you should use a dedicated, multi-valued, string syntax profile attribute that is obviously not used for other purposes. For example, you might call the attribute oAuth2SavedConsent.
  • Adding a profile attribute involves updating the identity repository to support use of the attribute, updating the AMUser Service for the attribute, and optionally allowing users to edit the attribute. The process is described in Developer's Guide › Customizing Profile Attributes which demonstrates adding a custom attribute when using OpenDJ directory services to store user profiles.

Known Issue

There is a known issue in 12.0.0, 12.0.1 and 12.0.2 which may cause the following error when configuring this: OPENAM-8374 (NullPointerException in OpenAMOAuth2ProviderSettings when saving consent):

ERROR: Unable to save consent
java.lang.NullPointerException

See Also

FAQ: OAuth 2.0 in AM/OpenAM

How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

How do I request further information (such as client_id or uid) for an OAuth 2.0 access token in AM/OpenAM (All versions)?

OAuth 2.0 Guide › AM as the OAuth 2.0 Authorization Server

OAuth 2.0 Guide › Managing OAuth 2.0 Consent

The OAuth 2.0 Authorization Framework - RFC6749

Related Training

N/A

Related Issue Tracker IDs

OPENAM-5093 (OAuth2 user consent confirmation can be optional )

OPENAM-6192 (For OAuth 2.0 don't expect the default Shared Consent Attribute to contain a value on first use)

OPENAM-8374 (NullPointerException in OpenAMOAuth2ProviderSettings when saving consent)

OPENAM-8375 (OAuth consent page shows 'save consent checkbox' although service property 'Saved Consent Attribute Name' of service 'OAuth Provider' has not been set)

OPENAM-8376 (Info text of service property 'Saved Consent Attribute Name' of service 'OAuth Provider' inaccurate)


Access Tokens and REST


How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

The purpose of this article is to provide information on performing common OAuth 2.0 tasks using curl commands with the standard OAuth2 endpoints in AM/OpenAM. This article provides example curl commands for common use cases including requesting authorization, requesting an access token and refreshing an access token across the different OAuth 2.0 grant types. It also provides an example curl command for checking an OAuth access token is still valid.

Overview

The following OAuth2 endpoints are used in AM/OpenAM:

Endpoint Description Standard
/oauth2/authorize Used to obtain an authorization grant from the resource owner. RFC 6749
/oauth2/access_token Used to obtain an access token from the authorization server. RFC 6749
/oauth2/device/code Used by a client device to obtain a device code (not available in pre-OpenAM 13). OAuth 2.0 Device Flow for Browserless and Input Constrained Devices (draft)
/oauth2/device/user Used by a client device to obtain an access token (not available in pre-OpenAM 13). OAuth 2.0 Device Flow for Browserless and Input Constrained Devices (draft)
/oauth2/token/revoke Lets administrators revoke access and refresh tokens (not available in pre-OpenAM 13). RFC 7009
/oauth2/introspect Used to retrieve metadata about a token, such as approved scopes and the context in which the token was issued. (not available in pre-OpenAM 13). RFC 7662
/frrest/oauth2/token (legacy)

Lets administrators read, list, and delete OAuth 2.0 tokens and includes information such as the creator of the token.

This endpoint is deprecated in AM 5 and later; you should use the /oauth2/introspect and /oauth2/token/revoke endpoints instead.

N/A

/oauth2/tokeninfo (legacy)

Used to validate tokens and to retrieve information about the token such as scopes.

This endpoint is legacy in AM 6.5 and later; you should use the /oauth2/introspect endpoint instead.

N/A

You should refer to OAuth 2.0 Endpoints and OAuth 2.0 Administration and Supporting REST Endpoints for further information and examples for the endpoints that are not defined in RFC 6749.  

Caution

The /oauth2/authorize endpoint requires the csrf parameter in AM, OpenAM 12.0.4, 13.5.x. The csrf parameter should equal the iPlanetDirectoryPro cookie value. See OpenAM 12 Release Notes › Important Changes to Existing Functionality in OpenAM 12.0.4 for further information.

Additionally, there are four grant types defined by RFC 6749, which determine how requests are made. The flows associated with these grant types are illustrated in OAuth 2.0 Guide › Implementing OAuth 2.0 Grant Flows.

This article provides example curl commands and/or URLs for the different flows associated with the four grant types defined by RFC 6749. It also provides an example for checking that an OAuth access token is still valid using the legacy /oauth2/tokeninfo endpoint. See OAuth 2.0 Guide › /oauth2/introspect for information on using the /oauth2/introspect endpoint instead. 

Authorization Code Grant

The authorization code grant type is used to obtain both access tokens and refresh tokens. Upon requesting authorization, a short-lived authorization code is returned, which can be used to obtain the access token. Example URLs and/or curl commands for the requests you can issue with this grant type are detailed below.

Requesting authorization

The parameters defined in RFC 6749 for requesting authorization are shown in the Authorization Request section of the RFC. As can be seen from the RFC, the response_type and client_id are required parameters.

The user should be sent to a URL such as the following in order that they can authenticate and give their consent (bypassing consent is against the standard): 

http://host1.example.com:8080/openam/oauth2/authorize?response_type=code&client_id=myClientID&redirect_uri=http://example.com/oauth

Example response:

HTTP/1.1 302 Found
Location: http://example.com:8080/oauth?code=7rQNrZ2CpyA8dshIJFn8SX43dAk&scope=openid%20profile&iss=http%3A%2F%2Fhost1.example.com%3A8080%2Fopenam%2Foauth2&state=af0ifjsldkj&client_id=myClientID
Note

There is a RFE to reduce the number of query parameters returned: OPENAM-13204 (OAuth2 Authorization Response - Additional query parameters are added in the redirect_URI). Per RFC 6749, the required code parameter is returned and any extra parameters will be ignored.

Requesting an access token

The parameters defined in RFC 6749 for requesting an access token for a user are shown in the Access Token Request section of the RFC. As can be seen from the RFC, the grant_type, code, redirect_uri and client_id are required parameters. client_secret is also required to allow the client to authenticate with the authorization server.

For example, to request an access token, you would use a curl command such as the following (where code is the authorization code you received when you requested authorization):

$ curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&code=362ad374-735c-4f69-aa8e-bf384f8602de&redirect_uri=http://example.com/oauth&client_id=myClientID&client_secret=myClientPassword" http://host1.example.com:8080/openam/oauth2/access_token

Example response:

{"scope":"cn","expires_in":599,"token_type":"Bearer","refresh_token":"534310ab-570b-4eb4-0ed7-d01d243fae21","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}

Refreshing an access token

The parameters defined in RFC 6749 for refreshing an access token are shown in the Refreshing an Access Token section of the RFC. As can be seen from the RFC, the grant_type and refresh_token are required parameters. client_id and client_secret are also required to allow the client to authenticate with the authorization server.

For example, to refresh an existing access token, you would use a curl command such as the following (where refresh_token is the refresh_token you received when you requested the access token):

$ curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=refresh_token&refresh_token=534310ab-570b-4eb4-0ed7-d01d243fae21&client_id=myClientID&client_secret=myClientPassword" http://host1.example.com:8080/openam/oauth2/access_token

Example response (where access token returned is different to the one initially returned when requesting the access token):

{"scope":"cn","expires_in":599,"token_type":"Bearer","access_token":"fd473223-8b1b-1b94-4f80-96923daa3237"}​

Implicit Grant

The implicit grant type is used to obtain an access token. This is a simplified flow compared to the authorization code grant type as an access token is issued immediately, although this can be considered less secure as the client is not authenticated. An example URL that can be used for the authorization request with this grant type is detailed below.

Requesting authorization

The parameters defined in RFC 6749 for requesting authorization are shown in the Authorization Request section of the RFC. As can be seen from the RFC, the response_type and client_id are required parameters.

The user should be sent to a URL such as the following in order that they can authenticate and give their consent (bypassing consent is against the standard): 

http://host1.example.com:8080/openam/oauth2/authorize?response_type=token&client_id=myClientID&redirect_uri=http://example.com/oauth

Example response:

HTTP/1.1 302 Found
Location: http://example.com/oauth/#token_type=Bearer&expires_in=599&access_token=fd473223-8b1b-1b94-4f80-96923daa3237

Resource Owner Password Credentials Grant

The resource owner password credentials grant type is used to obtain both access tokens and refresh tokens. Username and password are used to obtain the access token directly. This grant type should only be used when other grant types are not available and there is a great deal of trust between the resource owner and the client. Example curl commands for the requests you can issue with this grant type are detailed below.

Requesting an access token

The parameters defined in RFC 6749 for requesting an access token for a user are shown in the Access Token Request section of the RFC. As can be seen from the RFC, the grant_type, username and password are required parameters.

For example, to request an access token, you would use a curl command such as the following:

$ curl -X POST -u "myClientID:password" -d "grant_type=password&username=jdoe&password=changeit&scope=cn" http://host1.example.com:8080/openam/oauth2/access_token

Example response:

{"scope":"cn","expires_in":599,"token_type":"Bearer","refresh_token":"534310ab-570b-4eb4-0ed7-d01d243fae21","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}
Note

There is a known issue in AM / OpenAM 13.x, which means you must set the Token Endpoint Authentication Method to client_secret_post if you use scope=openid%20profile with the resource owner password credentials grant type. See invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x for further details.

Refreshing an access token

The parameters defined in RFC 6749 for refreshing an access token are shown in the Refreshing an Access Token section of the RFC. As can be seen from the RFC, the grant_type and refresh_token are required parameters.

For example, to refresh an existing access token, you would use a curl command such as the following (where refresh_token is the refresh_token you received when you requested the access token):

$ curl -X POST -u "myClientID:password" -d "grant_type=refresh_token&refresh_token=534310ab-570b-4eb4-0ed7-d01d243fae21" http://host1.example.com:8080/openam/oauth2/access_token

Example response (where access token returned is different to the one initially returned when requesting the access token):

{"scope":"cn","expires_in":599,"token_type":"Bearer","access_token":"fd473223-8b1b-1b94-4f80-96923daa3237"}​

Client Credentials Grant

The client credentials grant type is used to obtain an access token. Client credentials are used to obtain the access token directly. An example curl command for the access token request you can issue with this grant type is detailed below.

Requesting an access token

The parameters defined in RFC 6749 for requesting an access token for a client are shown in the Access Token Request section of the RFC. As can be seen from the RFC, the grant_type is the only required parameter.

For example, to request an access token, you would use a curl command such as the following:

$ curl -X POST -u "myClientID:password" -d "grant_type=client_credentials" http://host1.example.com:8080/openam/oauth2/access_token

Example response:

{"scope":"cn","expires_in":599,"token_type":"Bearer","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}

Checking an OAuth access token is valid (legacy)

You can use the legacy /oauth2/tokeninfo endpoint to validate an access token. For example, you would use a curl command such as the following:

$ curl -k 'http://host1.example.com:8080/openam/oauth2/tokeninfo?access_token=238beab2-b545-4fee-80fa-63f224bc56f6'

Example response:

{"scope":["cn"],"grant_type":"password","cn":"demo","realm":"/","token_type":"Bearer","expires_in":40,"access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}
Note

In OpenAM 12.0.1 and earlier, there is a known issue if the access token was obtained from a sub-realm:  OPENAM-6534 (Update OAuth2 tokeninfo endpoint to be realm-independent).

See Also

FAQ: OAuth 2.0 in AM/OpenAM

How do I request further information (such as client_id or uid) for an OAuth 2.0 access token in AM/OpenAM (All versions)?

How do I bypass the OAuth 2.0 Authorization Consent page in AM/OpenAM (All versions)?

invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x

OAuth 2.0 Guide › OAuth 2.0 Endpoints

OAuth 2.0 Guide › AM as the OAuth 2.0 Authorization Server

OAuth 2.0 Guide › Managing OAuth 2.0 Consent

The OAuth 2.0 Authorization Framework - RFC6749

Related Training

N/A

Related Issue Tracker IDs

OPENAM-13204 (OAuth2 Authorization Response - Additional query parameters are added in the redirect_URI)

OPENAM-6534 (Update OAuth2 tokeninfo endpoint to be realm-independent)

OPENAM-3506 (OAuth2 grant_type=client_credentials read/delete fail with NPE)


How do I request further information (such as client_id or uid) for an OAuth 2.0 access token in AM/OpenAM (All versions)?

The purpose of this article is to provide assistance with requesting further information such as client_id or uid (userName) for an OAuth 2.0 access token in AM/OpenAM. The response returned with the openam/oauth2/tokeninfo endpoint does not include this information by default.

Overview

An access token can either be obtained by a user or by an admin on behalf of a user; the approach you take depends on your workflow and which grant type you use.

This article gives examples of a user requesting an access token directly as well as examples of an admin performing the whole process, including obtaining an access token on behalf of a user.

Obtaining an access token (user)

The following examples show the implicit grant type being used to obtain an access token. You can use other grant types as shown in How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

Top level realm

You can send a user to a URL such as the following in order to obtain an access token: 

http://host1.example.com:8080/oauth2/authorize?response_type=token&client_id=myClientID&scope=cn&redirect_uri=http://www.forgerock.com

Example response:

https://www.forgerock.com/#scope=cn&token_type=Bearer&expires_in=3599&access_token=e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a

Subrealms

You can send a user to a URL such as the following in order to obtain an access token if they authenticated to a subrealm: 

http://host1.example.com:8080/oauth2/test/authorize?response_type=token&client_id=myClientID&scope=cn&redirect_uri=http://www.forgerock.com

Requesting further information about an access token

Note

Please observe the following when constructing REST calls:

  • Make the REST call to the actual AM/OpenAM server URL (not lb).
  • Change the name of the iPlanetDirectoryPro header to the name of your actual session cookie.
  • Set this session cookie header to the token returned when you authenticated.
  • Ensure the Accept-API-Version header contains valid resource versions (AM 5 and later).

See How do I avoid common issues with REST calls in AM/OpenAM (All versions)? for further information.

If you want to find out more about an access token (such as the client_id or userName) in the top level realm, you can use the ForgeRock specific endpoint:

  • /oauth2/token in AM 5 and later
  • /frrest/oauth2/token in OpenAM; this endpoint is deprecated in AM 5.

These endpoints are for administrators, meaning you must authenticate first in order to obtain a session token.

Requesting further information

  1. Authenticate as an admin user. For example:
    • AM 5 and later:
      $ curl -X POST -H "X-OpenAM-Username: amadmin" -H "X-OpenAM-Password: cangetinam" -H "Content-Type: application/json" -H "Accept-API-Version: resource=2.1"  http://host1.example.com:8080/openam/json/realms/root/authenticate
      
    • Pre-AM 5:
      $ curl -X POST -H "X-OpenAM-Username: amadmin" -H "X-OpenAM-Password: cangetinam" -H "Content-Type: application/json" http://host1.example.com:8080/openam/json/authenticate
    Example response:
    { "tokenId": "AQIC5wM2LY4SfcxsuvGEjcsppDSFR8H8DYBSouTtz3m64PI.*AAJTSQACMDIAAlNLABQtNTQwMTU3NzgxODI0NzE3OTIwNAEwNDU2NjE0*", "successUrl": "/openam/console", "realm": "/" } 
    
  2. Request an access token on behalf of a user using the following curl command with the resource owner password credentials grant type (ignore this step if the user has obtained the access token themselves):
    $ curl -X POST -u "myClientID:password" -d "grant_type=password&username=jdoe&password=changeit&scope=cn" http://host1.example.com:8080/openam/oauth2/access_token
    
    Example response:
    {"scope":"cn","expires_in":599,"token_type":"Bearer","refresh_token":"534310ab-570b-4eb4-0ed7-d01d243fae21","access_token":"e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a"}
    
  3. Request information about the token using one of the following curl commands:
    • AM 5 and later:
      $ curl -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" http://host1.example.com:8080/openam/oauth2/token/e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a
    • Pre-AM 5:
      $ curl -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" http://host1.example.com:8080/openam/frrest/oauth2/token/e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a
    Example response:
    {"_id":"id","_rev":"1465836044372","tokenName":["access_token"],"expireTime":["1465839520553"],"scope":["cn"],"grant_type":["password"],"clientID":["myClientID"],"parent":[],"id":["e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a"],"tokenType":["Bearer"],"auditTrackingId":["988a5d7f-1639-494f-abdf-7729e4f92a6a"],"realm":["/"],"nonce":[],"redirectURI":["http://www.forgerock.com"],"userName":["jdoe"]}
    

Subrealms

If you are querying an access token that exists for a user who authenticated to a subrealm and want to retrieve their user name, you should use the /oauth2/introspect endpoint. This endpoint is defined by RFC 7662 as of AM 5 and returns the user ID by default. See OAuth 2.0 Guide › /oauth2/introspect for further information.

In earlier versions, you will need to use openam/oauth2/tokeninfo endpoint but include the uid scope in both the OAuth provider configuration (Supported Scopes and Default Client Scopes) and the client configuration (Default Scopes and Scopes). See Reference › OAuth2 Provider and Administration Guide › Configuring OpenAM as Authorization Server and Client for further details on setting these scopes.

You can then use a curl command such as the following:

$ curl 'http://host1.example.com:8080/openam/oauth2/tokeninfo?access_token=e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a'

Example response:

{"uid":"demo","scope":["uid","cn"],"grant_type":"token","cn":"Demo User","realm":"/test","token_type":"Bearer","expires_in":3576,"access_token":"e1c9cf2f-6dd8-4f5e-8f0a-75671f6c132a"}

See Also

How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

How do I improve OAuth 2.0 performance in OpenAM 13.0?

FAQ: OAuth 2.0 in AM/OpenAM

OAuth 2.0 Guide › OAuth 2.0 Endpoints

Authentication and Single Sign-On Guide › Specifying Realms in REST API Calls

The OAuth 2.0 Authorization Framework - RFC6749

Related Training

N/A

Related Issue Tracker IDs

N/A


OIDC


How do I understand the JWTs used in OIDC that are generated or accepted by AM/OpenAM (All versions)?

The purpose of this article is to provide information on the JSON Web Tokens (JWTs) used in OpenID Connect 1.0 (OIDC) that are generated or accepted by AM/OpenAM.

JWTs in OIDC

The following table provides details on all the JWTs used in OIDC that AM/OpenAM generates or accepts:

Name Description Standards link Generated by Destination of Prerequisites Can be unsigned? Can be signed? Can be encrypted only? Can be signed and then encrypted? Can be encrypted and then signed?
ID Token Used by the Client application to get a representation of the authenticated user. OpenID Connect Core 1.0 › ID Token AM/OpenAM Client Must have OIDC scope in the request. -- Yes -- Yes --

Access Token

Used to access a resource. RFC 6749 › Access Token AM/OpenAM Client, Resource Server

Must have stateless sessions enabled.

Use Stateless Access & Refresh Tokens

-- Yes -- -- --
Refresh Token Used to generate a new access token. RFC 6749 › Refresh Token AM/OpenAM Client

Must have stateless sessions enabled.

Use Stateless Access & Refresh Tokens

-- Yes -- -- --
Client credential JWT

Used to authenticate the client application. By checking the signature, AM/OpenAM can be certain that the request was made by the client application, without needing the client credential in the POST parameter.

This is the recommended way to authenticate the client.

RFC 7523 › Using JWTs for Client Authentication Client and Resource Server * AM/OpenAM

Must set private_key_jwt as authentication method.

Token Endpoint Authentication Method

-- Yes -- -- --
User Info response You can encrypt an ID token to hide user information from the other party. If you need this feature, then you probably want to encrypt the user information response to ensure only the client application can access the users' information. OpenID Connect Core 1.0 › Successful UserInfo Response AM/OpenAM Client

Must configure the client configuration in AM/OpenAM to return a non-JSON format.

User info response format

Yes (in JSON format) Yes Yes Yes --
Request parameter

There are several reasons to use the request parameter, including the ability to obscure the request from the user by encrypting the request parameter. 

Using the request parameter with the authorization code grant flow is advised since this grant requires the user to interact; however, they will be able to read the request unless it is encrypted. 

There are other reasons to use the request parameter, which you can find in the standards section 6.

OpenID Connect Core 1.0 › Passing Request Parameters as JWTs Client AM/OpenAM Must send a request parameter when using the authorization code grant flow. Yes Yes -- Yes --

* Until section Using JWTs as Authorization Grants is implemented, the resource server needs to use the same key as the client application. The resource server can use the Client Credential JWT to introspect a JWT.

See Also

What federation standards does AM/OpenAM support?

OAuth 2.0 in AM/OpenAM

OpenID Connect 1.0 Guide

Related Training

ForgeRock Access Management Core Concepts (AM-400)

Related Issue Tracker IDs

N/A


How do I add custom claims to the OIDC Claims Script in AM (All versions) and OpenAM 13.x?

The purpose of this article is to provide information on adding custom claims to the OIDC Claims Script in AM/OpenAM and then obtaining the JWT ID token with the claims included.

Overview

AM 5.1 introduced improved OIDC claims support as detailed in AM 5.1 Release Notes › Major Improvements, which allows the use of the claims query parameter.

This article includes the following sections:

Adding custom claims to the script

The following process describes how to add custom claims to the OIDC Claims Script:

  1. Create a custom OIDC Claims Script by navigating to Realms > [Realm Name] > Scripts and clicking New Script. Enter a name for your script and select OIDC Claims as the script type.
  2. Specify the script details ensuring you make the following changes as needed:
    1. Declare any required classes in the import section at the top of the script.
    2. Add mapping details for the custom claim to the claimAttributes section. For example, a new customattr claim:
      // [ {claim}: {attribute retriever}, ... ]
      claimAttributes = [
              "email": userProfileClaimResolver.curry("mail"),
              ...
              "name": userProfileClaimResolver.curry("cn"),
              "customattr": userProfileClaimResolver.curry("customattribute")
      ]
      
    3. Add the custom claim to the scope in the scopeClaimsMap section. For example, with the new customattr claim added to a new custom scope (you could add your custom claim to the profile scope instead if you want to include it in the "Your personal information" section on the consent page):
      // {scope}: [ {claim}, ... ]
      scopeClaimsMap = [
              "email": [ "email" ],
              "address": [ "address" ],
              "phone": [ "phone_number" ],
              "profile": [ "given_name", "zoneinfo", "family_name", "locale", "name"],
              "custom": [ "customattr" ] 
      ]
      
  3. Ensure the custom attribute used for mapping in the claimAttributes section exists as a user attribute in your identity repository. See the Adding user attribute to the data store configuration section in How do I update LDAP user attributes using the REST API in AM/OpenAM (All versions)? for further information.
  4. Add any classes you declared in the import section to the Java class whitelist:
    • AM console: navigate to: Configure > Global Services > Scripting > Secondary Configurations > [Script Type] > Secondary Configurations > EngineConfiguration and add the Java class(es) to the Java class whitelist field.
    • OpenAM 13.5 console: navigate to: Configure > Global Services > Scripting > Secondary Configuration Instance > [Script Type] > Secondary Configuration Instance > Engine Configuration and add the Java class(es) to the Java class whitelist field.
    • OpenAM 13 console: navigate to: Configuration > Global > Scripting > Secondary Configuration Instance > [Script Type] > Secondary Configuration Instance > Engine Configuration and add the Java class(es) to the Java class whitelist field. 
  5. Update the OAuth2Provider to process claims correctly by navigating to Realms > [Realm Name] > Services > OAuth2 Provider (OpenAM 13.x does not have separate tabs, the following fields are on the same page):
    • Advanced tab - update the Supported Scopes field to include the scope you added in step 2c to display it on the consent page. For example, custom|en|Custom information will display the new custom scope in a Custom information section on the consent page.
    • OpenID Connect tab - select the OIDC claims script you created in step 1 in the OIDC Claims Script field.
    • OpenID Connect tab - update the Supported Claims field to include the custom claim (needed if you want to include claims when requesting an access token). For example, customattr|en|My custom attribute will display the new custom attribute on the consent page as My custom attribute.
    • Advanced OpenID Connect tab - enable the following options:
      • Enable "claims_parameter_supported" (needed if you want to include claims when requesting an access token)
      • Always Return Claims in ID Tokens
  6. Restart the web application container in which AM/OpenAM runs to complete this configuration.

Obtaining the JWT ID token using the authorize flow

The following example demonstrates obtaining the JWT ID token using the authorize flow, which includes the consent page:

  1. Initiate the flow by navigating to a URL such as the following:
    http://host1.example.com:8080/openam/oauth2/authorize?client_id=myClientID&redirect_uri=http://redirect.example.org&response_mode=form_post&response_type=code id_token&scope=openid profile custom&nonce=agreed
    
  2. Authenticate as normal; you will then be presented with the consent screen where you can observe the custom claim you added, for example:

  1. Provide consent; you will then be returned to redirect_uri with the code and id_token:
    http://redirect.example.org/#code=b9f41a4e-ffc7-4f50-838d-e26e7ed28e26&scope=openid%20profile%20custom&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdF9oYXNoIjoiR1pvZkhxYWV3QkoyaFJqa0tpVDhFdyIsInN1YiI6ImRlbW8iLCJhdWRpdFRyYWNraW5nSWQiOiIwZDgzNmE4ZC1hZjRjLTRiMzMtYTNhMi1iZjA2Y2Q1OTBiOTEtMzkzNyIsImlzcyI6Imh0dHA6Ly9ob3N0MS5leGFtcGxlLmNvbTo4MDgwL29wZW5hbS9vYXV0aDIiLCJ0b2tlbk5hbWUiOiJpZF90b2tlbiIsImF1ZCI6Im15Q2xpZW50SUQiLCJhenAiOiJteUNsaWVudElEIiwiYXV0aF90aW1lIjoxNTM4Njc1MjI2LCJuYW1lIjoiZGVtbyIsInJlYWxtIjoiLyIsImV4cCI6MTUzODczMzE1MiwidG9rZW5UeXBlIjoiSldUVG9rZW4iLCJmYW1pbHlfbmFtZSI6ImRlbW8iLCJjdXN0b21hdHRyIjoiY3VzdG9tIHZhbHVlIiwiaWF0IjoxNTM4Njc1MjI2LCJqdGkiOiJiYjE4YTQwNC1mMDhjLTQ0NmUtOGUwMS04YjcwYzhkNDgxOTIifQ.XFl_UfiGIar319V2GlYASkxsJCXiO_DE59cAryLq3d4
    
  2. Decode the id_token returned (for example, using https://jwt.davetonge.co.uk/) to verify that the JWT includes the custom claim (customattr in this example):
    {
     "at_hash":"GZofHqaewBJ2hRjkKiT8Ew"
     "sub":"demo"
     "auditTrackingId":"0d836a8d-af4c-4b33-a3a2-bf06cd590b91-3937"
     "iss":"http://host1.example.com:8080/openam/oauth2"
     "tokenName":"id_token"
     "aud":"myClientID"
     "azp":"myClientID"
     "auth_time":1538675226
     "name":"demo"
     "realm":"/"
     "exp":1538733152
     "tokenType":"JWTToken"
     "family_name":"demo"
     "customattr":"custom value"
     "iat":1538675226
     "jti":"bb18a404-f08c-446e-8e01-8b70c8d48192"
    }
    
Note

You can also use the idtokeninfo endpoint to validate the returned id_token as described in OpenID Connect 1.0 Guide › Validating OpenID Connect 1.0 ID Tokens.

Obtaining the JWT ID token using the claims query parameter (AM 5.1 and later)

The following example demonstrates the use of the claims query parameter in obtaining the JWT ID token:

  1. Generate an OIDC token, including the custom claim in JSON format with URL encoding (see Requesting Claims using the "claims" Request Parameter for further information):
    $ curl -s -X POST --user "myClientID:password" -d 'grant_type=password&username=demo&password=changeit&scope=profile%20openid&claims={"userinfo":{"customattr":{"essential":true}}%2C"id_token":{"customattr":{"essential":true}}}' "http://host1.example.com:8080/openam/oauth2/access_token"
    
    Example response:
    {"access_token": "1a58a25b-a2ac-4258-9708-905c449b8a6b","refresh_token": "e91bf8ee-1987-4daa-a7a5-26c35c78ea34","scope": "openid profile","id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdF9oYXNoIjoiR1pvZkhxYWV3QkoyaFJqa0tpVDhFdyIsInN1YiI6ImRlbW8iLCJhdWRpdFRyYWNraW5nSWQiOiIwZDgzNmE4ZC1hZjRjLTRiMzMtYTNhMi1iZjA2Y2Q1OTBiOTEtMzkzNyIsImlzcyI6Imh0dHA6Ly9ob3N0MS5leGFtcGxlLmNvbTo4MDgwL29wZW5hbS9vYXV0aDIiLCJ0b2tlbk5hbWUiOiJpZF90b2tlbiIsImF1ZCI6Im15Q2xpZW50SUQiLCJhenAiOiJteUNsaWVudElEIiwiYXV0aF90aW1lIjoxNTM4Njc1MjI2LCJuYW1lIjoiZGVtbyIsInJlYWxtIjoiLyIsImV4cCI6MTUzODczMzE1MiwidG9rZW5UeXBlIjoiSldUVG9rZW4iLCJmYW1pbHlfbmFtZSI6ImRlbW8iLCJjdXN0b21hdHRyIjoiY3VzdG9tIHZhbHVlIiwiaWF0IjoxNTM4Njc1MjI2LCJqdGkiOiJiYjE4YTQwNC1mMDhjLTQ0NmUtOGUwMS04YjcwYzhkNDgxOTIifQ.XFl_UfiGIar319V2GlYASkxsJCXiO_DE59cAryLq3d4","token_type": "Bearer","expires_in": 3599}
    
  2. Decode the id_token (for example, using https://jwt.davetonge.co.uk/) to verify that the JWT includes the custom claim (customattr in this example):
    {
     "at_hash":"GZofHqaewBJ2hRjkKiT8Ew"
     "sub":"demo"
     "auditTrackingId":"0d836a8d-af4c-4b33-a3a2-bf06cd590b91-3937"
     "iss":"http://host1.example.com:8080/openam/oauth2"
     "tokenName":"id_token"
     "aud":"myClientID"
     "azp":"myClientID"
     "auth_time":1538675226
     "name":"demo"
     "realm":"/"
     "exp":1538733152
     "tokenType":"JWTToken"
     "family_name":"demo"
     "customattr":"custom value"
     "iat":1538675226
     "jti":"bb18a404-f08c-446e-8e01-8b70c8d48192"
    }
    

Troubleshooting

This section details some common errors and how to remedy them:

Error message Resolution
Caused by: java.util.concurrent.ExecutionException: javax.script.ScriptException: javax.script.ScriptException: java.lang.SecurityException: Access to Java class \”className\” is prohibited.

The class must be added to the whitelist as shown in step 4 in Adding custom claims to the script.

See Access to Java class is prohibited error with scripts running in AM (All versions) and OpenAM 13.x for further information.

 "error_description": "Requested claims must be allowed by the client's configuration.",
 "error": "invalid_request"  )
The custom claim must be added to the Supported Claims field as shown in step 5 in Adding custom claims to the script.
"error_description": "Invalid%20JSON%20in%20supplied%20claims%20parameter in the return callback"
The claim needs to be passed in JSON format in the curl command as shown in Obtaining the JWT ID token using the claims query parameter (AM 5.1 and later).

See Also

How do I automate the creation of scripts in AM/OpenAM (All versions)?

How do I add logging to server-side scripts in AM (All versions) and OpenAM 13.x?

How do I understand the JWTs used in OIDC that are generated or accepted by AM/OpenAM (All versions)?

Creating OAuth2 Provider in AM 5.5.x and 6.x fails with a Could not initialise script configurations for realm error when using ssoadm

How do I modify the OIDC issuer ID or audience in a multi-server AM (All versions) environment?

FAQ: OAuth 2.0 in AM/OpenAM

OAuth 2.0 in AM/OpenAM

OpenID Connect 1.0 Guide

Development Guide › Developing with Scripts

Related Training

N/A

Related Issue Tracker IDs

OPENAM-11445 (Request to Customize OAuth2 Access Token Content)

OPENAM-10585 (The "claims" Request Parameter from the openid standard isn't functional)

OPENAM-10584 (Supported claims and scopes in OAuth2|OpenID provider are not hot swappable )

OPENAM-8440 (Pluggable OAuth2 Access Token Format)

OPENAM-7878 (Add functionality to modify the sub at the module level to override the clientID setting)


How do I add a roles claim to the OIDC Claims Script in AM (All versions) and OpenAM 13.x?

The purpose of this article is to provide information on adding a roles claim to the OIDC Claims Script in AM/OpenAM in order to return group membership details.

Overview

This article demonstrates how to add a roles claim to the OIDC Claims script; the script changes vary across versions:

See How do I add custom claims to the OIDC Claims Script in AM (All versions) and OpenAM 13.x? for further information on obtaining the JWT ID token with the claims included.

Adding a roles claim (AM 5 and later)

The following process describes how to add a roles claim to the OIDC Claims Script in order to return group membership details:

  1. Create a custom OIDC Claims Script by navigating to Realms > [Realm Name] > Scripts and clicking New Script. Enter a name for your script and select OIDC Claims as the script type.
  2. Specify the script details:
    1. Declare the com.sun.identity.idm.IdType class in the import section at the top of the script:
      import com.iplanet.sso.SSOException
      import com.sun.identity.idm.IdRepoException
      import org.forgerock.oauth2.core.exceptions.InvalidRequestException
      import org.forgerock.oauth2.core.UserInfoClaims
      import org.forgerock.openidconnect.Claim
      import com.sun.identity.idm.IdType
      
    2. Add mapping details for the roles claim to the claimAttributes section. You can reformat the claims value as required. For example (where the resulting group returned will be prefixed with ROLE_):
      // [ {claim}: {attribute retriever}, ... ]
      claimAttributes = [
              "email": userProfileClaimResolver.curry("mail"),
              ...
              "name": userProfileClaimResolver.curry("cn"),
              "roles": { claim, identity -> [ "roles" : identity.getMemberships(IdType.GROUP).collect { group -> 'ROLE_' + group.name }]}  
      ]
      
    3. Add the roles claim to the profile scope in the scopeClaimsMap section. For example:
      // {scope}: [ {claim}, ... ]
      scopeClaimsMap = [
              "email": [ "email" ],
              "address": [ "address" ],
              "phone": [ "phone_number" ],
              "profile": [ "given_name", "zoneinfo", "family_name", "locale", "name", "roles" ]
      ]
      
    4. Update any other script details as needed.
  3. Navigate to: Configure > Global Services > Scripting > Secondary Configurations > [Script Type] > Secondary Configurations > EngineConfiguration and add the com.sun.identity.idm.IdType class to the Java class whitelist field.
  4. Navigate to Realms > [Realm Name] > Services > OAuth2 Provider > OpenID Connect > OIDC Claims Script and select the OIDC claims script you created in step 1.
  5. Update the OAuth2Provider to process claims per your business requirements by navigating to Realms > [Realm Name] > Services > OAuth2 Provider. Settings you might want to change include:
    • OpenID Connect tab:
      • Update the Supported Claims field to include the roles claim (needed if you want to include claims when requesting an access token). For example, roles|en|Group membership will display the group membership details on the consent page as Group membership.
    • Advanced OpenID Connect tab - enable the following options:
      • Always Return Claims in ID Tokens (needed if you want claims returned in the ID token).
      • Enable "claims_parameter_supported" (needed if you want to include claims when requesting an access token).
  6. Restart the web application container in which AM runs to complete this configuration.

Adding a roles claim (OpenAM 13.x)

The following process describes how to add a roles claim to the OIDC Claims Script in order to return group membership details:

  1. Create a custom OIDC Claims Script by navigating to Realms > [Realm Name] > Scripts and clicking New Script. Enter a name for your script and select OIDC Claims as the script type.
  2. Specify the script details:
    1. Declare the com.sun.identity.idm.IdType class in the import section at the top of the script:
      import com.iplanet.sso.SSOException
      import com.sun.identity.idm.IdRepoException
      import org.forgerock.oauth2.core.UserInfoClaims
      import com.sun.identity.idm.IdType
      
    2. Add mapping details for the roles claim to the claimAttributes section. You can reformat the claims value as required. For example (where the resulting group returned will be prefixed with ROLE_):
      // [ {claim}: {attribute retriever}, ... ]
      claimAttributes = [
              "email": attributeRetriever.curry("mail"),
              ...
              "name": attributeRetriever.curry("cn"),
              "roles": { claim, identity, requested ->  identity.getMemberships(IdType.GROUP).collect { group -> 'ROLE_' + group.name } }
      ]
      
    3. Add the roles claim to the profile scope in the scopeClaimsMap section. For example:
      // {scope}: [ {claim}, ... ]
      scopeClaimsMap = [
              "email": [ "email" ],
              "address": [ "address" ],
              "phone": [ "phone_number" ],
              "profile": [ "given_name", "zoneinfo", "family_name", "locale", "name", "roles" ]
      ]
      
    4. Update any other script details as needed.
  3. Add the com.sun.identity.idm.IdType class to the Java class whitelist:
    • OpenAM 13.5 console: navigate to: Configure > Global Services > Scripting > Secondary Configuration Instance > [Script Type] > Secondary Configuration Instance > Engine Configuration and add the com.sun.identity.idm.IdType class to the Java class whitelist field.
    • OpenAM 13 console: navigate to: Configuration > Global > Scripting > Secondary Configuration Instance > [Script Type] > Secondary Configuration Instance > Engine Configuration and add the com.sun.identity.idm.IdType class to the Java class whitelist field.
  4. Navigate to Realms > [Realm Name] > Services > OAuth2 Provider > OIDC Claims Script and select the OIDC claims script you created in step 1.
  5. Update the OAuth2Provider to process claims per your business requirements by navigating to Realms > [Realm Name] > Services > OAuth2 Provider. Settings you might want to change include:
    • Update the Supported Claims field to include the roles claim (needed if you want to include claims when requesting an access token). For example, roles|en|Group membership will display the group membership details on the consent page as Group membership.
    • Enable the Always Return Claims in ID Tokens option (needed if you want claims returned in the ID token).
    • Enable the Enable "claims_parameter_supported" option (needed if you want to include claims when requesting an access token).
  6. Restart the web application container in which OpenAM runs to complete this configuration.

See Also

How do I automate the creation of scripts in AM/OpenAM (All versions)?

How do I add logging to server-side scripts in AM (All versions) and OpenAM 13.x?

How do I understand the JWTs used in OIDC that are generated or accepted by AM/OpenAM (All versions)?

Creating OAuth2 Provider in AM 5.5.x and 6.x fails with a Could not initialise script configurations for realm error when using ssoadm

How do I modify the OIDC issuer ID or audience in a multi-server AM (All versions) environment?

FAQ: OAuth 2.0 in AM/OpenAM

OAuth 2.0 in AM/OpenAM

OpenID Connect 1.0 Guide

Development Guide › Developing with Scripts

Related Training

N/A

Related Issue Tracker IDs

OPENAM-11445 (Request to Customize OAuth2 Access Token Content)

OPENAM-10585 (The "claims" Request Parameter from the openid standard isn't functional)

OPENAM-10584 (Supported claims and scopes in OAuth2|OpenID provider are not hot swappable )

OPENAM-8440 (Pluggable OAuth2 Access Token Format)

OPENAM-8270 (Using client_credentials Grant type with openid scope returns User must be authenticated to issue ID tokens.)

OPENAM-7878 (Add functionality to modify the sub at the module level to override the clientID setting)


How do I modify the OIDC issuer ID or audience in a multi-server AM (All versions) environment?

The purpose of this article is to provide information on modifying the OIDC issuer ID or audience contained in the JWT when you have a multi-server AM environment. This amendment is needed because the JWT must contain the issuer ID or audience applicable to the instance.

Background Information

A JWT can define the author of the JWT (Issuer ID) and the recipients of the JWT (audience):

  • Acting as the client application, your issuer ID is the client ID. This means:
    • when you send a JWT, you set the issuer ID to the client ID.
    • when you receive a JWT, you should check that the audience contains the client ID.
  • Acting as AM, the issuer ID is the Issuer URL, which is the oauth2 endpoint (for example, http://host1.example.com:8080/openam/oauth2). This means:
    • when you receive a JWT that has been generated by AM (such as an ID token), you need to check that the issuer ID is the appropriate URL.
    • when you send a JWT to AM (such as the client credential JWT or request parameter) you should ensure the audience contains the AM issuer ID (URL).

See the standards for further information about these attributes: RFC 7519 › "iss" (Issuer) Claim and RFC 7519 › "aud" (Audience) Claim.

Modifying the OIDC issuer and audience

You can modify the OIDC audience as follows for a multi-instance deployment; this process also changes the issuer ID:

  1. Add and configure the Base URL Source service using the console, Amster or ssoadm:
    • Console: Navigate to: Realms > [Realm Name] > Services > Add a Service > Base URL Source and click Create. Complete the following fields:
      • Base URL Source - set to FIXED_VALUE.
      • Fixed value base URL - enter the URL of the load balancer in front of your AM instances, for example, http://lb.example.com.
      • Extension class name - enter the following value:
        org.forgerock.openam.services.baseurl.BaseURLProvider
      • Context path - enter the deployment URI that you specified when you installed AM (this is /openam by default).
    • Amster: Use the create command with the BaseUrlSource entity as described in Entity Reference › BaseUrlSource, ensuring you set the properties as follows:
      source                  Fixed value
      fixedValue              [loadbalancerURL] 
      extensionClassName      org.forgerock.openam.services.baseurl.BaseURLProvider 
      contextPath             [contextPath]
      
      replacing [loadbalancerURL] and [contextPath] with appropriate values.
    • ssoadm:
      1. Create a data file (called DATA_FILE to match the next command) with the following contents:
        base-url-source=FIXED_VALUE
        base-url-fixed-value=[loadbalancerURL]
        base-url-extension-class=org.forgerock.openam.services.baseurl.BaseURLProvider
        base-url-context-path=[contextPath]
        
        replacing [loadbalancerURL] and [contextPath] with appropriate values.
      2. Enter the following command:
        $ ./ssoadm add-svc-realm -s amRealmBaseURL -e [realmname] -u [adminID] -f [passwordfile] -D DATA_FILE
        replacing [realmname], [adminID] and [passwordfile] with appropriate values.
  2. Set the "aud" in the inbound Request Object JWT. This value should consist of the fixed value base URL + the specified context path + /oauth2 + /realm. The /realm element is not required if this is configured in the top level realm. For example, based on the example values above where this is configured in the employees realm using the default context path, it would be:
    "aud": "http://lb.example.com/openam/oauth2/employees" 
    

See Also

OpenID Connect 1.0 Guide › Configuring the Base URL Source Service

How do I understand the JWTs used in OIDC that are generated or accepted by AM/OpenAM (All versions)?

AM/OpenAM (All versions) redirects to HTTP when deployed on Apache Tomcat with a load balancer doing SSL/TLS offloading

Related Training

N/A

Related Issue Tracker IDs

N/A


How do I transform an OIDC token to a SAML2 assertion in AM/OpenAM (All versions) using REST STS?

The purpose of this article is to provide information on configuring a REST STS (Secure Token Service) instance in AM/OpenAM for transforming an OpenID Connect (OIDC) token to a SAML2 assertion. This article assumes AM/OpenAM is acting as the OAuth Authorization server (OAuth2 provider), an OIDC token provider, and a REST STS consumer; it provides the necessary configuration steps for this setup, but you can exclude the relevant steps if you are using other providers in place of AM/OpenAM.

Overview

This article covers the following steps to configure the REST STS and then transform the OIDC token to SAML2:

  1. Create a REST STS instance
  2. Create a Service Provider
  3. Create an OAuth2 provider (skip this step if you are not using AM/OpenAM as the OAuth2 provider)
  4. Create an OIDC client (skip this step if you are not using AM/OpenAM as the OIDC server)
  5. Create an OIDC authentication module (skip this step if you are not using AM/OpenAM as the OIDC server)
  6. Transform an OIDC token to SAML2

Creating a REST STS instance

You can create a REST STS instance as follows (you can view example screenshots of this configuration in test_sts.pdf):

  1. Create a new REST STS instance using the console:
    • AM 6 and later console: navigate to Realms > [Realm Name] > STS and click Add REST STS.
    • Pre-AM 6 console: navigate to Realms > [Realm Name] > STS > Rest STS Instances and click Add.
  2. Complete the configuration of the STS instance; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead): 
    • Persist Issued Tokens in Core Token Store: option selected. 
    • Supported Token Transforms:
      UNT -> SAML2; invalidate interim OpenAM session
      OPENIDCONNECT -> SAML2; invalidate interim OpenAM session
    • Deployment Url Element: a string that identifies the REST STS instance, for example: test-sts. This string is used in the REST STS instance's endpoint.
    • The SAML2 issuer Id: sp.example.com
    • Service Provider Entity Id:  http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext
    • Token Lifetime (Seconds): 60000 - it is recommended to set this high to start with for testing purposes.
    • The id of the OpenIdConnect Token Provider: http://sp.example.com:8080/openam - this is the OpenID Connect agent name, which should also match the protocol://hostname:port/deploymentcontext.
    • Token Lifetime (Seconds): 60000 - again set high to start with for testing purposes.
    • Token signature algorithm: HMAC SHA 256
    • Client secret: the client secret used as the HMAC key - this is mandatory for HMAC-signed tokens.
    • The audience for issued tokens:  http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext.
  3. Restart the web application container in which AM/OpenAM runs to complete this configuration.
Note

You can also create a REST STS instance via ssoadm as detailed in How do I add and configure a REST STS instance in AM/OpenAM (All versions) using ssoadm? - you should use the settings described above.

Creating a Service Provider

You can create a Service Provider as follows:

  1. Navigate to:  Realms > [Realm Name] > Common Tasks > Configure SAMLv2 Provider > Create Hosted Service Provider
    • Name: http://sp.example.com:8080/openam
    • New Circle of Trust: cot

Creating an OAuth2 provider

If AM/OpenAM is acting as the OAuth2 provider, you should create this in the same realm as you created the REST STS instance (you can view example screenshots of this configuration in oauth_provider.pdf): 

  1. Navigate to: Realms > [Realm Name] > Common Tasks > Configure OAuth Provider > Configure OAuth 2.0 and populate the relevant details.
  2. Navigate to: Realms > [Realm Name] > Services > OAuth2 Provider and specify the supported scopes. You may need to add this service if it does not already exist.

Creating an OIDC client

If AM/OpenAM is acting as the OIDC server, you should create an OIDC client in the same realm as you created the REST STS instance (you can view example screenshots of this configuration in client.pdf):  

  1. Create a new OIDC client using the console:
    • AM 5.5 and later console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 and click Add Client.
    • AM 5 and 5.1.x console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 and click New.
    • OpenAM 13.x console: navigate to: Realms > [Realm Name] > Agents > OAuth 2.0/OpenID Connect Client and click New.
  2. Complete the configuration of the OIDC client; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead): 
    • Name: http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext.
    • Scope(s): cn, openid
    • Default Scope(s): cn, openid
    • Token Endpoint Authentication Method: client_secret_post - you must select this option if you use scope=openid%20profile with the resource owner password credentials grant type otherwise you will get an error when you do a POST request to the oauth2/access_token endpoint (invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x).
    • ID Token Signing Algorithm (AM / OpenAM 13.5) / ID Token Signed Response Algorithm (OpenAM 13.0): RS256 
Note

You can also create an OIDC client using REST as detailed in How do I create and update an agent in AM/OpenAM (All versions) using the REST API? - you should use the settings described above.

Creating OIDC authentication module

If AM/OpenAM is acting as the OIDC server, you should create an OpenID Connect id_token bearer authentication module in the same realm as you created the REST STS instance: 

Note

There is a known issue with creating and viewing the OpenID Connect id_token bearer type authentication module via the console in OpenAM 13.x: OPENAM-8290 (Impossible to create an 'OpenID Connect id_token bearer` module) so you should use the ssoadm instructions instead.

AM 5 and later console

  1. Navigate to: Realms > [Realm Name] > Authentication > Modules and click Add Module.
  2. Name the module oidc, select OpenID Connect id_token bearer and click OK. The module name must be oidc (all in lowercase) as this is used by REST STS to know which authentication context is used to validate the OpenID Connect token.
  3. Complete the configuration of the OpenID Connect id_token bearer authentication module; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead):
    • OpenID Connect validation configuration type: client_secret
    • OpenID Connect validation configuration value: password
    • Name of OpenID Connect ID Token Issuer: http://sp.example.com:8080/openam/oauth2
    • Mapping of jwt attributes to local LDAP attributes: sub=uid
    • Audience name: myClient
    • List of accepted authorized parties: myClient

ssoadm

  1. Use the following ssoadm command to create the OpenID Connect id_token bearer type authentication module:
    $ ./ssoadm create-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc -t OpenIdConnect
    replacing [adminID], [passwordfile] and [realmname] with appropriate values. The module name must be oidc (all in lowercase) as this is used by REST STS to know which authentication context is used to validate the OpenID Connect token.
  2. Create a data file (called data_file to match the next command) with the following contents, or download the sample data_file:
    openam-auth-openidconnect-crypto-context-value=http://sp.example.com:8080/openam/oauth2/.well-known/openid-configuration
    openam-auth-openidconnect-issuer-name=http://sp.example.com:8080/openam/oauth2
    openam-auth-openidconnect-audience-name=http://sp.example.com:8080/openam
    openam-auth-openidconnect-accepted-authorized-parties=http://sp.example.com:8080/openam
    You can add other attributes if required as per the available ones detailed in Authentication and Single Sign-On Guide › OpenID Connect id_token bearer Module.
Note

Setting openam-auth-openidconnect-crypto-context-type (OpenID Connect validation configuration type) to anything other than the default does not work. There is a known issue associated with the client_secret value: OPENAM-7887 (Unsupported Signing Algorithm, SHA256withRSA with Google issued JWT's).

  1. Run the following command to configure your new oidc module with these settings:
    $ ./ssoadm update-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc -D data_file
    replacing [adminID], [passwordfile] and [realmname] with appropriate values.
  2. You can check the settings for your new oidc module using the following command if required:
    $ ./ssoadm get-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc
    replacing [adminID], [passwordfile] and [realmname] with appropriate values.​

Transforming an OIDC token to SAML2

Restart your AM/OpenAM server before testing to ensure that all changes have been captured.

To perform the transformation, you make a REST call to the following endpoint:

/rest-sts/[instance]?_action=translate

where [instance] is the name of the REST STS instance, including the realm in which it exists. For example: employees/test-sts.

Example using curl

The following example obtains an OIDC token and then uses the REST STS instance (called test-sts in the employees realm) to transform that OIDC token to a SAML2 assertion: ​

  1. Request an OIDC token by making a REST call to the oauth2/access_token endpoint, which uses the client_secret_post authentication method. For example:
    $ curl -X POST -d '{ 
         "client_id=myClientID&client_secret=changeit&grant_type=password&username=jdoe&password=changeit&scope=openid%20profile" 
    }' http://host1.example.com:8080/openam/oauth2/access_token
    
    Example response:
    {"scope":"openid profile","expires_in":599,"token_type":"Bearer","id_token":"eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiLCAiY3R5IjogIkpXVCIsICJraWQiOiAiYTM3ZjE3YTItNjkzMi00YjAxLWFkZDUtOTM1YmU0N2E3NTI3IiB9.eyAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF6cCI6ICJteU9BdXRoMkNsaWVudCIsICJzdWIiOiAiZGVtbyIsICJhdF9oYXNoIjogIkVxV1JzNzlDMUVMVHBYazd6MU9pYVEiLCAiaXNzIjogImh0dHA6Ly9vYXV0aDJwcm92aWRlci5leGFtcGxlLm5ldDo1ODA4MC9vcGVuYW0vb2F1dGgyIiwgImlhdCI6IDE0NDE3MzI4NTMsICJhdXRoX3RpbWUiOiAxNDQxNzMyODUzLCAiZXhwIjogMTQ0MTczMzQ1MywgInRva2VuVHlwZSI6ICJKV1RUb2tlbiIsICJyZWFsbSI6ICIvIiwgImF1ZCI6IFsgIm15T0F1dGgyQ2xpZW50IiBdLCAib3BzIjogIjVmOGMyYWUzLTdkOTctNDNmNi04NGQ3LTI4YjgzYjNjNmUxNSIgfQ.wDh5UET7KuDLWc-enRpkLigqttYZ14PG2UIbmHOgAaM","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}
    
  2. Transform the received OIDC token to a SAML2 assertion by making a REST call to the /rest-sts/employees/test-sts?_action=translate endpoint. For example:
    $ curl -X POST -H "Content-Type: application/json" -d '{ 
         "input_token_state": { "token_type": "OPENIDCONNECT", "oidc_id_token": "eyAidHlwIjogIkp...-enRpkLigqttYZ14PG2UIbmHOgAaM" }, 
         "output_token_state": { "token_type": "SAML2", "subject_confirmation": "BEARER", "service_provider_assertion_consumer_service_url": "http://sp.example.com:8080/openam/users/metaAlias/sp" } 
    }' 'http://host1.example.com:8080/openam/rest-sts/employees/test-sts?_action=translate'
    
    Example SAML2 assertion returned:
    {"issued_token":"<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"s259f7ac265f109b3ddcc265267c3f3f3e80af4657\" IssueInstant=\"2015-09-08T17:21:27Z\" Version=\"2.0\">\n<saml:Issuer>ForgeRock</saml:Issuer><saml:Subject>\n<saml:NameID Format=\"urn:oasis:names:tc:SAML:1.0:nameid-format:unspecified\">jdoe</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\">\n<saml:SubjectConfirmationData NotOnOrAfter=\"2015-09-08T17:31:27Z\"/></saml:SubjectConfirmation>\n</saml:Subject><saml:Conditions NotBefore=\"2015-09-08T17:21:27Z\" NotOnOrAfter=\"2015-09-08T17:31:27Z\">\n<saml:AudienceRestriction>\n<saml:Audience>sp</saml:Audience>\n</saml:AudienceRestriction>\n</saml:Conditions>\n<saml:AuthnStatement AuthnInstant=\"2015-09-08T17:21:27Z\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>"}
    
    

See Also

Using the REST STS in AM/OpenAM

invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x

Security Token Service Guide

Related Training

N/A

Related Issue Tracker IDs

OPENAM-13337 (Upgrade OpenAM from 13.5.1 to AM 5.5.1 result in unable to obtain OAuth 2 access token)

OPENAM-8423 (Introduce "audience URL" attribute in OAuth2 client for Saml2GrantTypeHandler)

OPENAM-8290 (Impossible to create an 'OpenID Connect id_token bearer` module)

OPENAM-7887 (Unsupported Signing Algorithm, SHA256withRSA with Google issued JWT's)

OPENAM-6461 (Federation, SAE, & WSSAuthModule missing in new realm after default initial configuration)

OPENAM-6319 (OAuth2 scopes behaviour affected by the upgrade)


Frequently Asked Questions


FAQ: OAuth 2.0 in AM/OpenAM

The purpose of this FAQ is to provide answers to commonly asked questions regarding OAuth 2.0 and OpenID Connect 1.0 (OIDC) in AM/OpenAM.

Frequently asked questions

Q. What information is included in an OAuth 2.0 access token created by AM/OpenAM?

A. The following data is included:

  • EXPIRY_TIME - the time the token expires.
  • SCOPE - the scope of the token.
  • USER_NAME - the AM/OpenAM user who created the token.
  • REDIRECT_URI - the redirect URI used to create the token.
  • REFRESH_TOKEN - the ID of the refresh token for this access token.
  • REALM - the realm in which this access token was created.
  • ID - the ID of this access token.
  • CLIENT_ID - the client_id used to create the access token.
  • NONCE - the nonce value passed in as a parameter when requesting the access token.

Q. How can I check that an OAuth access token is valid?

A. You can use the following curl command to validate an access token:

$ curl -k 'http://host1.example.com:8080/openam/oauth2/tokeninfo?access_token=238beab2-b545-4fee-80fa-63f224bc56f6'
Note

In OpenAM 12.0.1 and earlier, there is a known issue if the access token was obtained from a sub-realm: OPENAM-6534 (Update OAuth2 tokeninfo endpoint to be realm-independent).

Q. Why is the OAuth access token still valid after the AM/OpenAM session has ended?

A. OAuth 2.0 does not check whether the assertion has been consumed or not; it only checks if it is valid. This means that even when an underlying AM/OpenAM session has ended (for example, there has been an IdP initiated single logout, the access token is still valid. The access token can be reused until the validity of the assertion has expired.

Note

AM/OpenAM provides an OAuth2 Post-Authentication Plugin as part of the standard product delivery. You can configure this plugin so that the OAuth2 authentication module logs the resource owner out with the OAuth 2.0 provider when logging out of AM. See Authentication and Single Sign-On Guide › Implementing Post-Authentication Plugins for further details and caveats.   

Q. Can I limit the number of OAuth 2.0 access tokens that can be issued per user?

A. No, you cannot do this within AM/OpenAM; the user can generate unlimited access tokens. You can constrain the use of tokens by applying a policy at token validation time; this is more in line with our continuous security approach.

Q. Can I modify the sub value to return a different user attribute in the id_token?

A. The sub (Subject Identifier) value maps to the stored Principal username of the underlying authentication module, that is, the LDAP Users Search Attribute. In AM 6 and later, you can override the sub claim by editing the OIDC Claims Script to manipulate the attributes returned in the id_token:

  1. Navigate to Realms > [Realm Name] > Scripts > OIDC Claims Script.
  2. Add the following new computedClaims.put line immediately before the final line in the script, for example:
    ...
    computedClaims.put("sub", identity.getAttribute("mail")[0])
    return new UserInfoClaims((Map)computedClaims, (Map)compositeScopes)
    
    where this new line overrides the sub value by mapping it to the mail attribute in the user's profile. You can map to other profile attributes in the same way.

When tested for the demo user, this amendment adjusts the sub value in the id_token from "demo" (the principal from the underlying authentication module, that is, the LDAP Users Search Attribute) to the user's email address. For example, the sub value in the generated id_token now looks like this:

{
  "at_hash": "m1ccfceGINU3d_TxJ9WiXQ",
  "sub": "demo@example.com",
...

The above assumes the option to "Always return claims in ID Tokens" in the OAuth2 Global service has been enabled. See OAuth 2.0 Guide › Advanced OpenID Connect for further details.

Resolved RFE: OPENAM-7878 (Add functionality to modify the sub at the module level to override the clientID setting)

Q. What parameters can I use with the oauth2/authorize and oauth2/access_token endpoints?

A. These endpoints are defined by the RFC 6749 standard. The oauth2/authorize endpoint can take realm, module and service parameters; the oauth2/access_token endpoint can take the realm parameter, and as of OpenAM 12.0.3, it can also take the auth_chain parameter. See OpenAM 12 Release Notes › What's New in OpenAM 12 › What's New in OpenAM 12.0.3 for further information.

If you want to specify a realm in the URL, you must use the realm parameter. For example, if the OAuth 2.0 provider is configured for the /employees realm, then use /oauth2/authorize?realm=/employees and /oauth2/access_token?realm=/employees. 

See OAuth 2.0 Guide › OAuth 2.0 Endpoints and How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)? for further information. These common use cases include requesting authorization, requesting an access token and refreshing an access token across the different OAuth 2.0 grant types (Authorization Code Grant, Implicit Grant, Resource Owner Password Credentials Grant and Client Credentials Grant).

Resolved RFE:  OPENAM-4177 (Update OAuth2 access_token endpoint to handle auth chain with non-name/password callback)

Q. Can I retrieve SSO session properties as claims via the OIDC /userinfo endpoint?

A. No, this is not possible because the AccessToken sent in the UserInfo request does not provide a link to the SSO session.

Q. Is it ok to expose these OAuth2 endpoints publicly?

A. The following OAuth2 endpoints have to be exposed in order for the OAuth functionality to work correctly:

  • /openam/oauth2/authorize
  • /openam/oauth2/tokeninfo
  • /openam/oauth2/access_token

Both the /authorize and /access_token endpoints require authentication; the /tokeninfo endpoint is open to everyone without authenticating to allow any user or application to validate a token. These endpoints are publicly documented in: OAuth 2.0 Guide.

You should also consult the RFC 6749, which discusses security considerations around OAuth2 endpoints.

Note

You should be aware that a specific type of request to the /frrest/oauth2/token endpoint can expose user tokens to another user as per OpenAM Security Advisory #201507. This endpoint is deprecated in AM 5 (and replaced with the /oauth2/token endpoint).

Q. What is the relationship between the Saved Consent Attribute Name and scopes?

A. The scope attribute in the authorization request lists the scopes that specify what type of access has been granted by the user. When a user is presented with a consent page and selects "Save consent", an entry will be added in the user profile containing the requested scope. See How does OAuth 2.0 Saved Consent work in AM/OpenAM (All versions)? for further information.

Q. How do I customize the Authorization Consent page (oauth2/authorize endpoint)?

A. This depends on what version of AM/OpenAM you are using:

AM 6.5

As of AM 6.5, you can customize this page (and other user-facing pages) on a per realm basis using the logo_uri, client_uri and policy_uri parameters (RFC 7591). See OAuth 2.0 Guide › Advanced for further information.

Pre-AM 6.5

The OAuth Authorization Consent page is rendered by a template (authorize.ftl). This template is located inside the openam-oauth2-x.x.x.jar (OpenAM 13.5 and later) or the oauth2-restlet-1x.0.x.jar (pre-OpenAM 13.5), which is in the WEB-INF/lib directory within openam.war.

Extract a version of the authorize.ftl file from the templates/page directory within the jar file and copy it to the /path/to/tomcat/webapps/openam/WEB-INF/classes/templates/pages directory where AM/OpenAM is deployed. You can then edit this file to customize the Authorization Consent page, ensuring you do not change any of the tags. Any changes you make in this way apply to all realms.

Q. How do I customize other OAuth 2.0 pages?

A. Similar to the Authorization Consent page, it depends on what version of AM/OpenAM you are using:

AM 6.5

As of AM 6.5, you can customize user-facing pages on a per realm basis using the logo_uri, client_uri and policy_uri parameters (RFC 7591). See OAuth 2.0 Guide › Advanced for further information.

Pre-AM 6.5

The other OAuth 2.0 pages are rendered by template files (*.ftl). These template files are located inside the openam-oauth2-x.x.x.jar (OpenAM 13.5 and later) or the oauth2-restlet-1x.0.x.jar (pre-OpenAM 13.5), which is in the WEB-INF/lib directory within openam.war.

Extract a version of the required *.ftl file from the templates/ directory within the jar file and copy it to the corresponding /path/to/tomcat/webapps/openam/WEB-INF/classes/templates/ directory where AM/OpenAM is deployed. You can then edit this file to customize the page, ensuring you do not change any of the tags. Any changes you make in this way apply to all realms.

Q. Is it possible to bypass the Authorization Consent page?

A. You can bypass the OAuth 2.0 Authorization Consent page in AM/OpenAM when you are using the Authorization Code Grant flow as detailed in How do I bypass the OAuth 2.0 Authorization Consent page in AM/OpenAM (All versions)?

Q. Is it possible to bypass consent during Dynamic Client Registration?

A. No, you cannot set the Implied Consent option to true during Dynamic Client Registration as this is against the OAuth 2.0 standard (RFC 6749).

See OPENAM-12831 (OAuth2 and OpenIDConnect allow implied consent to be defined in dynamic registration) for further information and possible alternative solutions.

Q. What scopes can I request with the default Scope validator in AM/OpenAM?

A. As of OpenAM 13, you can use any user attribute as a scope. Additionally, the following attributes no longer have hard-coded mappings:

  • email
  • address
  • phone  

Resolved RFE: OPENAM-4459 (OpenID Connect attribute mappings should be localizable)

In pre-OpenAM 13, you can request the following scopes using the default scope validator:

  • email
  • address
  • phone
  • profile - this scope also contains the following additional user information: cn, givenname, sn, preferredlocale and preferredtimezone.
  • openid

If you require any other scopes, you need to implement a custom validator class as discussed in OAuth 2.0 Guide › Customizing OAuth 2.0 Scope Handling.

Q. How does the OAuth 2.0 authentication module create a session?

A. The OAuth2 authentication module links an OAuth2 access token (whether from AM/OpenAM or any OAuth 2.0 provider) to a local user; it uses the access token to receive information about the user (such as their email address), links it to a local user and returns a session. Although the AM/OpenAM session timeout and the OAuth 2.0 token timeout are independent of each other, you can refresh or renew an expired AM/OpenAM session without providing credentials again if the refresh token is still valid.

For example, if your OAuth 2.0 provider is Google™ and your AM/OpenAM session expires, you can send another authorization request to Google; Google will then refresh your AM/OpenAM session (without requiring your credentials) providing the refresh token is still valid. If the refresh token is not valid, you will need to re-authenticate to continue.

Note

OAuth2 is an authorization protocol and using it as described above to create a session is using it as an authentication protocol. We imply authentication whilst the access token (being a bearer token) could be presented or replayed by anyone. Implying authentication through OAuth 2.0 is standard practice though and is therefore offered by AM/OpenAM. OpenAM 12.0.0 offers a new OpenID Connect authentication module, which is designed for Authentication; this should be used instead of the OAuth2 authentication module for authentication purposes.

See the following for further information:

Q. Can I use the OAuth 2.0 authentication module with the Distributed Authentication Service (DAS)?

A. No, this is not possible because the OAuth authentication module is not included in DAS. DAS has been removed as of OpenAM 13.

See Also

How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

How do I request further information (such as client_id or uid) for an OAuth 2.0 access token in AM/OpenAM (All versions)?

How do I improve OAuth 2.0 performance in OpenAM 13.0?

OAuth 2.0 in AM/OpenAM

Authentication and Single Sign-On Guide › Social Authentication Module Properties - OAuth 2.0

Authentication and Single Sign-On Guide › Social Authentication Module Properties - OpenID Connect 1.0

OAuth 2.0 Guide

Related Issue Tracker IDs

OPENAM-6061 (ftl files should be customizable like other UI pages)


FAQ: UMA in AM/OpenAM

The purpose of this FAQ is to provide answers to commonly asked questions regarding User-Managed Access (UMA) in AM/OpenAM. AM 5.5 does not support UMA 1.0; UMA 2.0 is supported instead.

Frequently asked questions

Q. Can I share UMA resources with a group?

A. No this is not currently possible. The current implementation of UMA sharing in AM/OpenAM is based on user-to-user sharing, meaning userA can share something with userB. Additionally, all users need to be valid users in AM/OpenAM.

Q. Can a resource provider use the introspect endpoint to check tokens received by clients?

A. This is possible as of OpenAM 13.5.2. The implementation in earlier versions only allowed the introspect endpoint to be called by the client who requested the Requesting Party Token (RPT). See RFC 7662: OAuth 2.0 Token Introspection for further information about the applicable standard.

Resolved RFE: OPENAM-8983 (introspect endpoint shouldn't be limited to the same client as token)

See Also

User-Managed Access (UMA) 2.0 Guide

User-Managed Access (UMA) Guide

Related Issue Tracker IDs

OPENAM-7232 (In XUI policy editor OAuth2Providers wizard crested policy, does not have a subject)

OPENAM-8832 (user_access_policy_uri is not formed correctly for UMA)

OPENAM-8875 (Install/Upgrade steps missing for UMA directory entry on External config store)

OPENAM-9067 (UMA policy cannot be viewed in Policy Editor)


Known Issues


redirect_uri_mismatch error occurs when using AM/OpenAM (All versions) as an OAuth 2.0 / OpenID client or provider

The purpose of this article is to provide assistance if you receive a "redirect_uri_mismatch" error (Description: The redirection URI provided does not match a pre-registered value) when using AM/OpenAM as an OAuth 2.0 / OpenID client and/or provider.

Symptoms

The following error is shown in the browser:

Error: redirect_uri_mismatch
Description: The redirection URI provided does not match a pre-registered value.

Recent Changes

Implemented a Social Authentication module (OAuth 2.0 or OpenID Connect 1.0) in AM 5.5 or later to make AM an OAuth / OpenID client.

Implemented the OAuth 2.0/OpenID Connect authentication module in pre-AM 5.5 to make AM/OpenAM an OAuth / OpenID client.

Configured AM/OpenAM as an OAuth Authorization Server (with or without the OpenID Connect authentication layer) to make AM/OpenAM an OAuth / OpenID provider. In this setup, you would also have configured OAuth 2.0/OpenID Connect Client agents to connect to and use your authorization server.

Added an AngularJS based application to your OAuth / OpenID setup.

Causes

The redirection URI is missing, it contains a fragment (#) (which is against the OAuth2 standard) or the redirection URI parameter being sent does not match the one registered for your client.

The default routing mode in AngularJS is hashbang (#!), which includes these fragments in the redirection URI.

Solution

This issue can be resolved by ensuring the redirection URI is the same in both the client and provider, and the endpoint URI does NOT contain a fragment per RFC 6749. If a fragment is unavoidable, you can try URL encoding it.

Refer to the following subsections depending on what you are trying to achieve and your AM/OpenAM version:

Note

If you have multiple attribute values for ssoProxyUrl or iplanet-am-auth-oauth-sso-proxy-url when changing the redirection URI via ssoadm you can use -D [datafile] instead of -a to add the attribute values from a file. See How do I add multiple attributes with a single ssoadm command in AM/OpenAM (All versions)? for further information.

Changing the redirection URI if AM is the OAuth client (AM 5.5 and later)

You can change the redirection URI at the global or realm level if AM is the OAuth client using either the console or ssoadm:

  • Global level:
    • AM 5.5 and later console: navigate to: Configure > Authentication > Social Auth OAuth2 > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm set-attr-defs -s iPlanetAMAuthSocialAuthOAuth2Service -t organization -u [adminID] -f [passwordfile] -a ssoProxyUrl=[URI]
      
      replacing [adminID], [passwordfile] and [URI] with appropriate values.
  • Realm level:
    • AM 5.5 and later console: navigate to: Realms > [Realm Name] > Authentication > Modules > [Social Auth OAuth2 Module] > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm update-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m [modulename] -a ssoProxyUrl=[URI]
      
      replacing [adminID], [passwordfile], [realmname], [modulename] and [URI] with appropriate values.

Changing the redirection URI if AM is the OpenID client (AM 5.5 and later)

You can change the redirection URI at the global or realm level if AM is the OpenID client using either the console or ssoadm:

  • Global level:
    • AM 5.5 and later console: navigate to: Configure > Authentication > Social Auth OpenID > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm set-attr-defs -s iPlanetAMAuthSocialAuthOpenIDService -t organization -u [adminID] -f [passwordfile] -a ssoProxyUrl=[URI]
      
      replacing [adminID], [passwordfile] and [URI] with appropriate values.
  • Realm level:
    • AM 5.5 and later console: navigate to: Realms > [Realm Name] > Authentication > Modules > [Social Auth OpenID Module] > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm update-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m [modulename] -a ssoProxyUrl=[URI]
      
      replacing [adminID], [passwordfile], [realmname], [modulename] and [URI] with appropriate values.

Changing the redirection URI if AM/OpenAM is the client (OpenAM and pre-AM 5.5)

You can change the redirection URI at the global or realm level if AM/OpenAM is the client using either the console or ssoadm:

  • Global level:
    • OpenAM 13.5 / Pre-AM 5.5 console: navigate to: Configure > Authentication > OAuth 2.0 / OpenID Connect > Proxy URL and specify the redirection URI.
    • Pre-OpenAM 13.5 console: navigate to: Configuration > Authentication > OAuth 2.0 / OpenID Connect > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm set-attr-defs -s sunAMAuthOAuthService -t organization -u [adminID] -f [passwordfile] -a iplanet-am-auth-oauth-sso-proxy-url=[URI]
      
      replacing [adminID], [passwordfile] and [URI] with appropriate values.
  • Realm level:
    • OpenAM 13.x / Pre-AM 5.5 console: navigate to: Realms > [Realm Name] > Authentication > Modules > [OAuth 2.0 / OpenID Connect Module] > Proxy URL and specify the redirection URI.
    • Pre-OpenAM 13 console: navigate to: Access Control > [Realm Name] > Authentication > Module Instances > [OAuth 2.0 / OpenID Connect Module] > Proxy URL and specify the redirection URI.
    • ssoadm: enter the following command:
      $ ./ssoadm update-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m [modulename] -a iplanet-am-auth-oauth-sso-proxy-url=[URI]
      
      replacing [adminID], [passwordfile], [realmname], [modulename] and [URI] with appropriate values.

Changing the redirection URI if AM/OpenAM is the provider 

You can change the redirection URI if AM/OpenAM is the provider using either the console or ssoadm:

  • AM 5 and later console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 > [Client ID] > Redirection URIs and specify one or more valid redirection URIs.
  • OpenAM 13.x console: navigate to: Realms > [Realm Name] > Agents > OAuth 2.0/OpenID Connect Client > [Client Name] > Redirection URIs and specify one or more valid redirection URIs.
  • Pre-OpenAM 13 console: navigate to: Access Control > [Realm Name] > Agents > OAuth 2.0/OpenID Connect Client > [Client Name]  > Redirection URIs and specify one or more valid redirection URIs. 
  • ssoadm: enter the following command:
    $ ./ssoadm update-agent -e [realmname] -b [clientname] -u [adminID] -f [passwordfile] -a com.forgerock.openam.oauth2provider.redirectionURIs[0]=[URI]
    replacing [realmname], [clientname], [adminID], [passwordfile] and [URI] with appropriate values. You can add as many redirection URIs as required by adding multiple com.forgerock.openam.oauth2provider.redirectionURIs [n] properties separated by a space and ensuring the [n] increments for each additional redirection URI. For example:
    $ ./ssoadm update-agent -e employees -b OAuthAgent -u amadmin -f pwd.txt -a com.forgerock.openam.oauth2provider.redirectionURIs[0]=http://host1.example.com:8080/%23/app
    com.forgerock.openam.oauth2provider.redirectionURIs[1]=http://host2.example.com:18080
    

If multiple redirection URIs are registered, the client must specify the URI that the user should be redirected to following approval. 

Note

You must ensure both the client and provider use the same redirection URI. If AM/OpenAM is being used for both the client and provider, you should set the same URI in both places as detailed above.

URL encoding the endpoint URI

You can try URL encoding the endpoint URI if a fragment is unavoidable, for example, a URL that currently looks like:

http://host1.example.com:8080/#/app

should be changed to:

http://host1.example.com:8080/%23/app
Note

URL encoding does not always work if you have an AngularJS based application, as AngularJS needs the # to route internally. You can workaround this by having a redirection URI without the fragment; for example, a jsp page, which interprets the request and appends the required #/<route> to the URI before it gets to your application or something like OpenIG; OpenIG cannot intercept # fragments either, so it needs to intercept requests without #.

See Also

OAuth 2.0 Authorization Framework RFC 6749 (Section 3.1.2.2) Registration Requirements

OpenID Connect Core 1.0 - Redirect URI Fragment Handling Implementation Notes

Authentication and Single Sign-On Guide › Social Authentication Module Properties - OAuth 2.0

Authentication and Single Sign-On Guide › Social Authentication Module Properties - OpenID Connect 1.0

AM 5 Authentication and Single Sign-On Guide › Implementing Authentication › OAuth 2.0/OpenID Connect Authentication Module

OAuth 2.0 Guide

OpenID Connect 1.0 Guide

Related Training

N/A

Related Issue Tracker IDs

OPENAM-2575 (Misleading description text in Oauth2 client registration page)

OPENAM-6871 (Request to improve Redirection URI description)

OPENAM-8330 (OAuth Redirect URI for subrealm does not handle # properly causing a redirect uri mismatch)


Unable to retrieve certificate with alias 'test' from keystore after making changes to the keystore in AM (All versions)

The purpose of this article is to provide assistance if you receive an "Internal Server Error" response to the jwk_uri or the well-known OAuth2 endpoints in AM after making changes to the keystore. You will also see the following error in the logs: "Unable to retrieve certificate with alias 'test' from keystore". This issue also occurs when IDM is integrated with AM with a "Cannot find resolver for issuer" error.

Symptoms

For calls made to the jwk_uri endpoint or the well-known endpoint, for example:

  • GET http://host1.example.com:8080/openam/oauth2/realms/root/connect/jwk_uri
  • GET http://host1.example.com:8080/openam/oauth2/realms/root/.well-known/openid-configuration

You will receive the following response (or possibly an empty response):

{"error":"server_error","error_description":"Internal Server Error"} 

The following error is shown in the OAuth2Provider debug log (warning or message level) when this happens:

OAuth2Provider:03/08/2018 10:22:57:121 AM MDT: Thread[tomcat-http--22,5,main]: TransactionId[269d260b-ebd3-4014-b6f0-13eaa880161f-1034]
WARNING: Unhandled exception: Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request
Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request
   at org.restlet.resource.ServerResource.doHandle(ServerResource.java:539)
   at org.restlet.resource.ServerResource.get(ServerResource.java:742)
   at org.restlet.resource.ServerResource.doHandle(ServerResource.java:617)
...
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
   at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
   at org.forgerock.oauth2.core.AgentOAuth2ProviderSettings.getJWKSet(AgentOAuth2ProviderSettings.java:363)
   at org.forgerock.openidconnect.restlet.OpenIDConnectJWKEndpoint.getJWKSet(OpenIDConnectJWKEndpoint.java:73)
...

An error similar to the following is shown in the CoreSystem debug log at the same time:

amSecurity:03/08/2018 10:22:57:116 AM MDT: Thread[tomcat-http--22,5,main]: TransactionId[269d260b-ebd3-4014-b6f0-13eaa880161f-1034]
ERROR: Unable to retrieve certificate with alias 'test' from keystore '/path/to/openam/keystore.jks'

IDM/AM integration

If you have integrated IDM with AM, you will see the following error in the IDM log when this happens:

Caused by: org.forgerock.oauth.OAuthException: Cannot find resolver for issuer https://host1.example.com:8080/openam/oauth2
   at org.forgerock.oauth.clients.oidc.OpenIDConnectClient.lambda$getJwtClaimsSet$3(OpenIDConnectClient.java:367)
   at java.util.Optional.orElseThrow(Optional.java:290)
   at org.forgerock.oauth.clients.oidc.OpenIDConnectClient.getJwtClaimsSet(OpenIDConnectClient.java:367)
   at org.forgerock.oauth.clients.oidc.OpenIDConnectClient.lambda$validateNonce$0(OpenIDConnectClient.java:270)
...

Recent Changes

Upgraded to AM 5 or later.

Created a new keystore.

Changed the default key alias (called test).

Causes

AM 5 introduced a new configuration property for the signing key alias used by Agents 5, which defaults to test. If you have changed your keystore and/or the default key alias without updating this key alias, you will see this error.

Solution

This issue can be resolved by updating the key alias used by Agents 5 using either the console, Amster or ssoadm:

  • Console: navigate to: Configure > Global Services > OAuth2 Provider > Global Attributes > ID Token Signing Key Alias for Agent Clients and update the test key alias to one that exists.
  • Amster: follow the steps in How do I update property values in AM (All versions) using Amster? with these values:
    • Entity: OAuth2Provider
    • Property: agentIdTokenSigningKeyAlias
  • ssoadm: enter the following command:
    $ ./ssoadm set-attr-defs -s OAuth2Provider -t global -u [adminID] -f [passwordfile] -a agentIdTokenSigningKeyAlias=[keyAlias]
    replacing [adminID], [passwordfile] and [keyAlias] with appropriate values.

You should double-check you have updated the key alias in all the places noted in the documentation: Setup and Maintenance Guide › Changing Default Key Aliases.

See Also

Cannot recover key error shown when renewing expired certificates or changing the password for the keystore or truststore in AM/OpenAM (All versions)

How do I update the certificate alias for the signing key in the AM/OpenAM (All versions) keystore?

How does the OIDC authorization flow work when IDM (All versions) is integrated with AM?

OpenID Connect 1.0 Guide › OAuth2 Provider

Related Training

N/A

Related Issue Tracker IDs

OPENAM-11492 (OpenID Jwk_uri URL returns Internal Server Error )


Unhandled exception: Internal Server Error (500) when running OIDC_CLAIMS scripts under load in AM (All versions)

The purpose of this article is to provide assistance if you encounter "Unhandled exception: Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request" when running OIDC_CLAIMS scripts under load in AM. Examples of this may be performance testing concurrent logins with repeated requests to the OIDC userinfo endpoint or load testing with repeated requests to the access_token endpoint.

Symptoms

You receive the following 400 response to the request:

{"code":400,"reason":"The request could not be understood by the server due to malformed syntax"}

The following error is shown in the OAuth2Provider debug log when this happens:

OAuth2Provider:10/01/2019 09:43:39:492 AM GMT: Thread[http-nio-8080-exec-40,5,main]: TransactionId[50321dff-a328-4d40-9527-9fc53d1740b1-21332]
ERROR: Unhandled exception: 
Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request
   at org.restlet.resource.ServerResource.doHandle(ServerResource.java:539)
   at org.restlet.resource.ServerResource.get(ServerResource.java:742)
   at org.restlet.resource.ServerResource.doHandle(ServerResource.java:617)
   at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:678)
   at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:356)
   at org.restlet.resource.ServerResource.handle(ServerResource.java:1043)
...
Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@3aba1094 rejected from java.util.concurrent.ThreadPoolExecutor@4552b7f2[Running, pool size = 50, active threads = 50, queued tasks = 10, completed tasks = 204]
   at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
   at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
   at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
   at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)

Recent Changes

N/A

Causes

AM does not have a sufficient number of threads available to run the scripts, which causes the scripts to be blocked. The threads available are determined by two settings: Maximum thread pool size and Thread pool queue size as described here: Reference › Engine Configuration.

These settings default to 50 and 10 respectively, but it is recommended they are set to 300 and -1 instead.

Solution

This issue can be resolved by tuning these thread settings appropriately for your environment. It is suggested you start with the recommended settings.

You can tune these settings using either the console, Amster or ssoadm:

  • AM console: navigate to: Configure > Global Services > Scripting > Secondary Configurations > [Script Type] > Secondary Configurations > EngineConfiguration and enter new values for Maximum thread pool size (recommended setting = 300) and Thread pool queue size (recommended setting = -1).
  • Amster: follow the steps in How do I update property values in AM (All versions) using Amster? with these values:
    • Entity: ScriptingEngineConfiguration
    • Property: maxThreads​​​​​​​ and queueSize​​​​​​​
  • ssoadm: enter the following command:
    $ ./ssoadm set-sub-cfg -s ScriptingService -g OIDC_CLAIMS/engineConfiguration -u [adminID] -f [passwordfile] -o set -a maxThreads=[maxThreads] queueSize=[queueSize] 
    replacing [adminID], [passwordfile], [maxThreads] and [queueSize] with appropriate values.
Note

You must restart the web application container in which AM runs to apply these configuration changes.

See Also

How do I add custom claims to the OIDC Claims Script in AM (All versions) and OpenAM 13.x?

OAuth 2.0 in AM/OpenAM

Performance tuning and monitoring ForgeRock products

OpenID Connect 1.0 Guide

Related Training

N/A

Related Issue Tracker IDs

OPENAM-13270 (EngineConfiguration settings need clarification)

OPENAM-11778 (Getting accessToken using authorization_code result in Unhandled exception)

OPENAM-9307 (Significant number of internal errors while generating access_token load)


Addition of the standard header "Pragma" is discouraged errors when AM 5, 5.1.x and OpenAM 13.5 is configured as an OAuth Provider

The purpose of this article is to provide assistance if you encounter "Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it." warning messages when AM/OpenAM is configured as an OAuth Provider.

Symptoms

The same error is shown in the web application container log (for example, catalina.out for Apache Tomcat™), but may take a slightly different format; these formats include:

WARNING [https-jsse-nio-8443-exec-3] org.restlet.engine.header.HeaderUtils.addExtensionHeaders Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it.
org.restlet.engine.header.HeaderUtils addExtensionHeaders 
WARNING: Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it.
WARNING [org.restlet.Component.LogFilter] (http-/127.0.0.1:8443-7) Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it. 

Recent Changes

Upgraded to AM 5 or 5.1.x.

Upgraded to OpenAM 13.5.

Configured AM/OpenAM as an OAuth Provder.

Causes

HTTP header information exists that currently cannot be translated using the Restlet API, but will be supported in the future. See Restlet Framework - Mapping HTTP headers Introduction for further information.

Solution

Firstly, this error is harmless and can be ignored. However, this issue can be resolved by upgrading to AM 5.5 and later, or OpenAM 13.5.1; you can download this from BackStage.

See Also

N/A

Related Training

N/A

Related Issue Tracker IDs

OPENAM-9885 (Oauth2 load: Tomcat keeps logging "WARNING: Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it.")


invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x

The purpose of this article is to provide assistance if you receive an "invalid_client" error when requesting an OAuth 2.0 access token in AM/OpenAM. This error happens when the Token Endpoint Authentication Method is set to client_secret_basic (which is the default method) and the resource owner password credentials grant type is either password or client_credentials.

Symptoms

One of the following errors is shown when requesting an OAuth 2.0 access token with the Token Endpoint Authentication Method set to client_secret_basic, and the grant_type set to password or client_credentials. For example:

  • grant_type=password and scope=openid%20profile:
    $ curl -X POST -d "client_id=myClientID&client_secret=password&grant_type=password&username=jdoe&password=changeit&scope=openid%20profile" http://host1.example.com:8080/openam/oauth2/access_token
    
    {"error":"invalid_client","error_description":"Invalid authentication method for accessing this endpoint."} 
  •  grant_type=client_credentials:
    $ curl -X POST -d "grant_type=client_credentials&client_id=myClientID&client_secret=password" http://host1.example.com:8080/openam/oauth2/access_token
    
    {"error":"invalid_client","error_description":"Client authentication failed"}

Recent Changes

Upgraded to, or installed AM 5 or later.

Upgraded to, or installed OpenAM 13.x.

Causes

The wrong authentication method is being used for requests that have the resource owner password credentials grant type and the openid scope or a grant type of client_credentials.

This may appear to be a regression issue since these requests worked in OpenAM 12.x, but that was because the Token Endpoint Authentication Method could not be set and nor was it checked. OpenAM 13.x introduced the ability to set the method (this method only applies to the openid scope) and also checks for compliance, meaning that non-compliant requests that worked in OpenAM 12.x will no longer work.

Solution

This issue can be resolved by setting the Token Endpoint Authentication Method to client_secret_post.

You can set the Token Endpoint Authentication Method using either the console or ssoadm:

  • AM 5.5 and later console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 > [Client ID] > Advanced > Token Endpoint Authentication Method and select the client_secret_post option.
  • AM 5 and 5.1.x console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 > [Client Name] > Token Endpoint Authentication Method and select the client_secret_post option.
  • OpenAM 13.x console: navigate to: Realms > [Realm Name] > Agents > OAuth 2.0/OpenID Connect Client > [Client Name] > Token Endpoint Authentication Method and select the client_secret_post option.
  • ssoadm: enter the following command:
    $ ./ssoadm update-agent -e [realmname] -b [clientname] -u [adminID] -f [passwordfile] -a com.forgerock.openam.oauth2provider.tokenEndPointAuthMethod=client_secret_post
    replacing [realmname], [clientname], [adminID] and [passwordfile] with appropriate values.

See Also

How do I perform common OAuth 2.0 tasks using curl commands with the standard endpoints in AM/OpenAM (All versions)?

OAuth 2.0 Guide › Reference › OAuth 2.0 and OpenID Connect 1.0 Client Settings

Related Training

N/A

Related Issue Tracker IDs

OPENAM-7169 (Can't use the "client_secret_basic" method type with the password grant type and openid scope)

OPENAM-7334 (Client Authentication method not compliant with OpenID standard)

OPENAM-7336 (Field "Token Endpoint Authentication Method" in the OAuth2 agent profile not clear)

OPENAM-9676 (Request to oauth2/access_token with query string fails with 'Invalid Content Type' in 13.x)


Access to Java class is prohibited error with scripts running in AM (All versions) and OpenAM 13.x

The purpose of this article is to provide assistance if you encounter a "javax.script.ScriptException: java.lang.SecurityException: Access to Java class "class.name" is prohibited" error when using functionality that is based on a script in AM/OpenAM. This issue might occur when validating or processing a script such as a policy condition script or an OIDC claims script.

Symptoms

Errors similar to the following are shown when executing your script:

Caused by: java.util.concurrent.ExecutionException: javax.script.ScriptException: javax.script.ScriptException: java.lang.SecurityException: Access to Java class "groovy.json.internal.LazyMap" is prohibited.
Caused by: java.util.concurrent.ExecutionException: javax.script.ScriptException: javax.script.ScriptException: java.lang.SecurityException: Access to Java class \”com.sun.identity.idm.IdType\” is prohibited.

Recent Changes

Created or updated a script.

Causes

The specified Java® class has not been added to the whitelist, which means it cannot be invoked by the script.

Solution

This issue can be resolved by adding the specified Java class to the whitelist using either the console or ssoadm:

  • AM / OpenAM 13.5 console: navigate to: Configure > Global Services > Scripting > Secondary Configurations > [Script Type] > Secondary Configurations > EngineConfiguration and add the missing Java class to the Java class whitelist field.
  • OpenAM 13.0 console: navigate to: Configuration > Global > Scripting > Secondary Configuration Instance > [Script Type] > Secondary Configuration Instance > Engine Configuration and add the missing Java class to the Java class whitelist field. 
  • ssoadm:
    1. Run the following command to create a data file (called DATA_FILE to match the next command), which is populated with the current whiteList property values to ensure you don't lose any existing changes:
      $ ./ssoadm get-sub-cfg -s ScriptingService -g [scriptType] -u [adminID] -f [passwordfile] | grep whiteList > DATA_FILE
      
      replacing [scriptType], [adminID] and [passwordfile] with appropriate values, where [scriptType] must equal one of the following depending on your script type:
      Script Type -g value
      Policy Condition POLICY_CONDITION/engineConfiguration
      Server-side Authentication AUTHENTICATION_SERVER_SIDE/engineConfiguration
      OIDC Claims OIDC_CLAIMS/engineConfiguration
    2. Update the data file you just created by adding the required whiteList values at the end in the same format as the rest of the file (whiteList=java.class).
    3. Run the following command to update the whiteList property values:
      $ ./ssoadm set-sub-cfg -s ScriptingService -g [scriptType] -u [adminID] -f [passwordfile] -o add -D DATA_FILE
      replacing [scriptType], [adminID] and [passwordfile] with appropriate values, where [scriptType] must match the value you used in step 1.

Example

If you received the "Access to Java class "groovy.json.internal.LazyMap" is prohibited" error message (shown in the Symptoms) when validating a policy using a policy condition script, you can resolve it as follows:

  1. Retrieve the current whiteList settings for the Policy Condition script type and save them to a file using the following ssoadm command:
    $ ./ssoadm get-sub-cfg -s ScriptingService -g POLICY_CONDITION/engineConfiguration -u amadmin -f pwd.txt | grep whiteList > whitelist.txt
    
  2. Verify that the whiteList attributes have been saved to the file, for example:
    $ cat whitelist.txt
    
    Example Response:
    whiteList=java.lang.Float
    whiteList=java.util.HashMap$KeyIterator
    whiteList=com.sun.identity.shared.debug.Debug
    whiteList=java.lang.Double
    whiteList=org.forgerock.openam.scripting.api.http.JavaScriptHttpClient 
    ...
    
  3. Add the missing Java class to the text file, for example:
    $ echo whiteList=groovy.json.internal.LazyMap >> whitelist.txt
    
  4. Verify that the new whiteList attribute has been added to this file, for example:
    $ cat whitelist.txt
    
    Example Response:
    whiteList=java.lang.Float
    whiteList=java.util.HashMap$KeyIterator
    whiteList=com.sun.identity.shared.debug.Debug
    whiteList=java.lang.Double
    whiteList=org.forgerock.openam.scripting.api.http.JavaScriptHttpClient 
    ...
    whiteList=groovy.json.internal.LazyMap
    
  5. Update the whiteList property values with the ones in the file using the following ssoadm command:
    $ ./ssoadm set-sub-cfg -s ScriptingService -g POLICY_CONDITION/engineConfiguration -u amadmin -f pwd.txt -o set -D whitelist.txt
    
  6. Check the whiteList settings (including the new Java class) have been applied successfully using the following ssoadm command:
    $ ./ssoadm get-sub-cfg -s ScriptingService -g POLICY_CONDITION/engineConfiguration -u amadmin -f pwd.txt
    
    Example Response:
    queueSize=10 
    i18nKey=engine-configuration 
    useSecurityManager=true 
    idleTimeout=60 
    blackList=java.lang.Class 
    blackList=java.security.AccessController 
    blackList=java.lang.reflect.* 
    coreThreads=10 
    whiteList=java.lang.Float
    whiteList=java.util.HashMap$KeyIterator
    whiteList=com.sun.identity.shared.debug.Debug
    whiteList=java.lang.Double
    whiteList=org.forgerock.openam.scripting.api.http.JavaScriptHttpClient
    ...
    whiteList=groovy.json.internal.LazyMap
    maxThreads=50 
    serverTimeout=0 
    
    Sub Configuration ScriptingService was retrieved.

See Also

How do I create a policy condition script in AM/OpenAM (All versions)?

How do I add logging to server-side scripts in AM (All versions) and OpenAM 13.x?

How do I automate the creation of scripts in AM/OpenAM (All versions)?

Reference › Configuration Reference › Scripting

Related Training

N/A

Related Issue Tracker IDs

N/A


Creating OAuth2 Provider in AM 5.5.x and 6.x fails with a Could not initialise script configurations for realm error when using ssoadm

The purpose of this article is to provide assistance if you encounter a "Could not initialise script configurations for realm" error when trying to create an OAuth2 Provider in AM using ssoadm.

Symptoms

A blank response is shown when using a command such as the following to create the OAuth2 Provider:

$ ./ssoadm add-svc-realm -s OAuth2Provider -e / -u amadmin -f pwd.txt -D oauth2providerconfig.txt

Where the oauth2providerconfig.txt file contains the forgerock-oauth2-provider-oidc-claims-extension-script attribute. 

The AM console does not show the creation of the OAuth2Provider.

Debug log

You will see the following error in the ssoadm Configuration debug log when this happens:

amCLI:02/08/2018 09:27:45:487 PM GMT: Thread[main,5,main]: TransactionId[unknown]
ERROR: An unexpected error occurred in thread 'Thread[main,5,main]'
java.lang.IllegalStateException: Could not initialise script configurations for realm /
   at org.forgerock.openam.scripting.service.ScriptConfigurationService.reload(ScriptConfigurationService.java:130)
   at org.forgerock.openam.scripting.service.ScriptConfigurationService.init(ScriptConfigurationService.java:115)
   at org.forgerock.openam.scripting.service.ScriptConfigurationService.<init>(ScriptConfigurationService.java:111)
   at org.forgerock.openam.scripting.service.ScriptChoiceValues.getScriptingService(ScriptChoiceValues.java:116)
   at org.forgerock.openam.scripting.service.ScriptChoiceValues.getChoiceValues(ScriptChoiceValues.java:88)
   at com.sun.identity.sm.AttributeSchemaImpl$AttributeSchemaState.getChoiceValuesMap(AttributeSchemaImpl.
...
Caused by: org.forgerock.openam.scripting.ScriptException: Script type not recognised: AUTHENTICATION_TREE_DECISION_NODE

Recent Changes

Upgraded to, or installed AM 5.5 or later.

Causes

The introduction of authentication tree nodes in AM 5.5 has caused an issue with modifying the script configuration in the OAuth2 provider service. The presence of the forgerock-oauth2-provider-oidc-claims-extension-script attribute prevents the OAuth2 provider being created or the custom script being updated for existing providers.

Solution

This issue can be resolved using one of the following approaches:

  • Use Amster to create the OAuth2 provider
  • Use the REST API to create the OAuth2 provider
  • Exclude the problematic attribute and create the OAuth2 provider using ssoadm
Note

Since ssoadm is deprecated as of AM 5, this known issue will not be resolved.

Use Amster to create the OAuth2 provider

Create the OAuth provider as described in: Entity Reference › OAuth2Provider › create.

Use the REST API to create the OAuth2 provider

Note

Please observe the following when constructing REST calls:

  • Make the REST call to the actual AM/OpenAM server URL (not lb).
  • Change the name of the iPlanetDirectoryPro header to the name of your actual session cookie.
  • Set this session cookie header to the token returned when you authenticated.
  • Ensure the Accept-API-Version header contains a valid resource version (AM 5 and later).

See How do I avoid common issues with REST calls in AM/OpenAM (All versions)? for further information.

You can create the OAuth2 provider using the /realm-config/services/oauth-oidc REST endpoint​. You can use the API Explorer to try out this endpoint as detailed in Development Guide › Introducing the API Explorer, which will provide the OAuth2 provider data you should include in the REST call or you can query the OAuth2 provider service first as demonstrated in the following example:

  1. Authenticate as an admin user. For example:
    $ curl -X POST -H "X-OpenAM-Username: amadmin" -H "X-OpenAM-Password: cangetinam" -H "Content-Type: application/json" -H "Accept-API-Version: resource=2.1"  http://host1.example.com:8080/openam/json/realms/root/authenticate
    
    Example response:
    { "tokenId": "AQIC5wM2LY4SfcxsuvGEjcsppDSFR8H8DYBSouTtz3m64PI.*AAJTSQACMDIAAlNLABQtNTQwMTU3NzgxODI0NzE3OTIwNAEwNDU2NjE0*", "successUrl": "/openam/console", "realm": "/" }
    
  2. Retrieve the OAuth2Provider service details using the following curl command:
    $ curl -X GET -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" http://host1.example.com:8080/openam/json/realms/root/realm-config/services/oauth-oidc 
    
    Example response (this has been truncated due to the size of response):
    {
        "_id": "",
        "_rev": "-2046488110",
        "coreOAuth2Config": {
            "refreshTokenLifetime": 604800,
    ...
    ...
      "_type": {
        "_id": "oauth-oidc",
        "name": "OAuth2 Provider",
        "collection": false
      }
    }
    
    
  3. Create the OAuth2 provider using the following curl command; the data option should include the response from step 2 with the configuration updated for the new provider, and the first _id and _rev fields removed, for example:
    $ curl -X PUT -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" -H "Accept-API-Version: resource=1.0" -d '{
        "coreOAuth2Config": {
            "refreshTokenLifetime": 604800,
    ...
    ...
      "_type": {
        "_id": "oauth-oidc",
        "name": "OAuth2 Provider",
        "collection": false
      }
    }' http://host1.example.com:8080/openam/json/realms/root/realm-config/services/oauth-oidc
    
    Example response (this has been truncated due to the size of response):
    {
        "_id": "",
        "_rev": "-870213730",
        "coreOAuth2Config": {
            "refreshTokenLifetime": 604800,
    .........
        "_type": {
            "_id": "oauth-oidc",
            "name": "OAuth2 Provider",
            "collection": false
        }
    }
    

Exclude the problematic attribute and create the OAuth2 provider using ssoadm

  1. Remove the following attribute from your OAuth2 provider configuration file:
    forgerock-oauth2-provider-oidc-claims-extension-script
  2. Re-run the ssoadm command to create the OAuth2 provider, for example:
    $ ./ssoadm add-svc-realm -s OAuth2Provider -e / -u amadmin -f pwd.txt -D oauth2providerconfig.txt
  3. Add the custom claims script in the AM console by navigating to: Realms > [Realm Name] > Services > OAuth2 Provider > OpenID Connect > OIDC Claims Script and adding your custom claims script.

See Also

OAuth 2.0 in AM/OpenAM

Using Amster in AM

Using the REST API in AM/OpenAM

Reference › OAuth2 Provider

Related Training

N/A

Related Issue Tracker IDs

OPENAM-12305 (ssoadm does not create OAuth2Provider service)


Copyright and TrademarksCopyright © 2018 - 2019 ForgeRock, all rights reserved.

This content has been optimized for printing.

Loading...