Authentication with OAuth 2

You can use an OAuth 2 access token to issue REST APIs on Oracle Fusion Cloud EPM to satisfy the requirement of avoiding the use of passwords in your environment.

Note:

If you are configuring OAuth 2.0 for the first time, follow the procedures in Setting Up Authentication with OAuth 2. If you already have an existing OAuth 2.0 configuration, see Updates to Existing Configuration for the steps required to update your configuration.

Updates to Existing Configuration

If you have an existing OAuth 2.0 configuration, your current grant type can continue to be used. However, the following updates are required:

  • Update the Integrated Application - Add the appropriate EPM Cloud Service resource to the Integrated Application. A single Integrated Application can include multiple EPM Cloud Service resources.

    For detailed instructions, see step 11(a-g) in Detailed Information for Using Oracle Cloud Console to Register an OAuth 2 Client.

  • Update Oracle Cloud Services - Update the Secondary Audience for each EPM Cloud Service under the Oracle Cloud Services tab. If the Refresh Token grant type is enabled for the Integrated Application, enable the Allow token refresh option.

    For detailed instructions, see Step 2: Configure the Secondary Audience and Enable Token Refresh for EPM Cloud Services.

  • Access Token Scope
    • Update the scope used when requesting an access token. Use the EPM Cloud Service-specific scope when requesting an access token. The scope is in the following format:
      urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all
    • For Device Code with Refresh Token integrations, delete the existing refresh token and generate a new first refresh token using the EPM Cloud Service-specific scope.

      See Step 3: Obtain and securely store the first refresh token for more details.

    Note:

    A token can be used only with the EPM Cloud Service resource for which it was created. If you access multiple EPM Cloud Service resources, you must obtain a separate token for each resource.

Setting Up Authentication with OAuth 2

This section describes how to configure a new OAuth 2 client for Cloud EPM REST API access. If you are updating an existing OAuth 2 client, see Updates to Existing Configuration instead.

In order to access Cloud EPM REST APIs with OAuth 2, a Cloud EPM Service Administrator has to request the Domain Administrator to set up an OAuth 2 client and provide the Identity Domain Cloud Service (IDCS) URL and Client ID.

Overview of the steps:

About Copying Code Samples

Do not copy code samples from the PDF version of this document. To avoid line breaks and footer information that will render code unusable, Oracle recommends that you copy code samples from the HTML version of the examples in this guide.

The following sections provide detailed information about each step.

Step 1: Register an OAuth Client

Registering an OAuth client is a one-time process. The first step is to update the service provider configuration to authorize requests from the REST client application. As a security measure, any client application that accesses Oracle Cloud resources must be authorized to do so. An IDCS Administrator enables this authorization by registering a client and providing the appropriate registration information to the client's users.

A client application in IDCS is used to obtain an access token. A valid access token (also called a Bearer token) is sufficient authorization to invoke a REST API.

Oracle Fusion Cloud Enterprise Performance Management uses a role-based access control mechanism to permit only authorized users access to the service. For details, see About User and Role Management. This requires that any OAuth 2 access token used to access Cloud EPM REST APIs contains a user context.

A grant type is a standard method to obtain an access token. There are a few different Grant Types as listed here that could be used to obtain an access token. An access token obtained by any of the supported grant types is acceptable as long as the access token is in the context of the user that would be invoking the REST APIs.

In this document, we describe the use of the Device Code Grant Type. EPM Automate has built-in support for the Device Code Grant type.

While the Device Code grant type would work in a majority of environments, it might not be right for every implementation. Any of the grant types that allow creating an access token with a user context would be suitable for Cloud EPM REST APIs. In addition to the Device Code grant type, the following grant types support access tokens in the context of an end user:

The next section highlights the steps to create a sample OAuth 2 client using the Device Code grant type to request an access token. It also demonstrates how to use the access token to invoke the Get Daily Maintenance Window REST API.

Refer to the Oracle Identity Cloud Service documentation for more details on the Supported Access Grant Types.

The Identity Cloud Service Administrator follows the steps in this topic to create a public client using the Identity Cloud Service Administrator console. The IDCS Administrator then shares the Identity Cloud Service tenant URLand client ID with the Cloud EPM Service Administrator.

Follow the instructions in Detailed Information for Using Oracle Cloud Console to Register an OAuth 2 Client.

Detailed Information for Using Oracle Cloud Console to Register an OAuth 2 Client

  1. Log in to your account at https://cloud.oracle.com/

  2. Click the Navigation menu, select Identity & Security, and then select Domains.

  3. From the Domains page, select the identity domain where your Cloud EPM services are deployed. This opens the domain details page.

  4. On the domain details page, note the Domain URL. This URL is used as the tenant base URL for OAuth 2.0 token requests.

  5. From the domain page, select the Integrated applications tab.

  6. Click Add application.

  7. On the Add application page, select Mobile Application, then click Launch workflow.

  8. On the Add Mobile Application page, enter the Name and Description for the application. Leave the remaining fields at their default values, and click Submit.

  9. After clicking Submit, the application is created and opens on the Details tab. Click the OAuth configuration tab.

  10. On the OAuth configuration tab, click Edit OAuth configuration. Under Client configuration > Authorization > Allowed grant types, select Refresh token and Device code, and ensure Implicit is not selected.

  11. In the Token Issuance policy section:

    1. Enable Add Resources.

    2. Click Add Scope.

    3. In the Add Scope slide in, select the EPM applications for which this Integrated Application will act as the client. You can select multiple EPM applications by selecting the checkbox next to each application.

    4. Click Add to confirm your selection.

    5. Verify that the selected EPM Cloud resources appear in the Resources table.

    6. Note the scope associated with each selected resource. This value will be required when requesting access tokens later.

    7. Scope is of the form:
      urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all
    8. Enable Add app roles.

    9. Click the Add roles button.

    10. Choose Identity Domain Administrator on the slide-in dialog box.

    11. Click the Add button to close the slide-in dialog box.

  12. Click Submit to save the OAuth configuration. After the changes are saved, click Actions > Activate, and then click Activate application to activate the application.
  13. Note the Client ID value in the General Information section of the OAuth Configuration.

The IDCS Administrator provides the IDCS URL and client ID to the Cloud EPM Service Administrator.

Step 2: Configure the Secondary Audience and Enable Token Refresh for EPM Cloud Services

The EPM Cloud Service Administrator for the EPM Cloud resource added to the Integrated Application in step 11(c) logs in to the Oracle Cloud Console using an account from the identity domain where the EPM application is provisioned, and then navigates to the Oracle Cloud Services tab for that identity domain.

Note:

The following steps must be completed for each EPM Cloud Service

  1. Click the EPM Cloud service selected during step 11(c).

  2. Click the OAuth configuration tab.

  3. Click Edit OAuth configuration.

  4. Enable Add secondary audience.

  5. Add the base URL for the EPM Cloud Service.

    1. Derive the base URL of the service from the URL by removing the trailing context path.
    2. For example, if an EPM Cloud Service is accessed using the following URL:
      https://<instance-name>-test-<cloud-account-name>.epm.<region>.ocs.oraclecloud.com/epmcloud
      the secondary audience is
      https://<instance-name>-test-<cloud-account-name>.epm.<region>.ocs.oraclecloud.com
  6. Enable the Allow token refresh option only if the Integrated Application has the Refresh Token grant type enabled.

    Use the slider to enable or disable Allow token refresh for the EPM Cloud Service.

  7. Save the changes.

Step 3: Obtain and securely store the first refresh token

Note:

When requesting the first refresh token, use the EPM Cloud Service-specific scope in the following format:

urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all offline_access

A refresh token created using this scope is valid only for the associated EPM Cloud Service resource.

After the Domain Administrator has registered the REST client and provided the IDCS URL and client ID, a Cloud EPM user executes the following steps to get a valid refresh token.

  1. Issue the following unauthenticated request to the Identity Cloud Service URL:

    Linux

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/device' \
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' \
    --data-urlencode 'response_type=device_code' \
    --data-urlencode 'scope=urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all offline_access' \
    --data-urlencode 'client_id=<CLIENT ID OF OAUTH2 APPLICATION>'

    Windows Powershell

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/device' `
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' `
    --data-urlencode 'response_type=device_code' `
    --data-urlencode 'scope=urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all offline_access' `
    --data-urlencode 'client_id=<CLIENT ID OF OAUTH2 APPLICATION>'

    Windows Command Prompt

    curl --location --request POST "https://tenant-base-url/oauth2/v1/device" ^
    --header "Content-Type: application/x-www-form-urlencoded;charset=utf-8" ^
    --data-urlencode "response_type=device_code" ^
    --data-urlencode "scope=urn:opc:serviceInstanceID=<SERVICE_INSTANCE_ID>urn:opc:resource:consumer::all offline_access" ^
    --data-urlencode "client_id=<CLIENT ID OF OAUTH2 APPLICATION>"

    Here, the value of tenant-base-url is the IDCS URL provided by the Domain Administrator or the Domain URL from the IAM console. It is of the form idcs-<alphanumericvalue>.identity.oraclecloud.com. Similarly, the value for the CLIENT ID OF THE OAUTH2 APPLICATION is also provided by the Domain Administrator or retrieved from the Application's General Information section in IAM. It is an alphanumeric value. The variable <SERVICE_INSTANCE_ID> in the scope is the unique identifier for that resource. Refer to step 11(f) and step 11(g), where you were asked to note this scope.

    A valid response contains a device code, user code, and verification URI:

    {
      "expires_in": 300,
      "device_code": "4d03f7bc-f7a5-4795-819a-5748c4801d35",
      "user_code": "SDFGHJKL",
      "verification_uri": "https://tenant-base-url/ui/v1/device"
    }

    The user_code from the response is needed in the second step below, while device_code from the response is needed in the third step below.

    Note: Steps 2 and 3 are time-sensitive because the user code and device code expire 300 seconds (5 minutes) after creation. If the codes expire before these steps can be completed, redo the first step of this section to issue an unauthenticated request to the IDCS URL to receive a new pair of user and device codes.

  2. Open the verification_uri in a supported web browser.

    At this stage, it is important to know that if a user already has an active browser session, the user will not be prompted for re-authentication. If the token is to be generated in context of the currently signed-in user, then proceed with 2b. However, if the token is to be generated in the context of a different user, please sign-out of the current session and navigate to the verification_uri and continue with 2a.

    1. When prompted for credentials, authenticate the user who will be invoking the REST API. These credentials could be credentials for a SAML 2.0 compliant Identity Provider or a native IDCS credential.
    2. When prompted for a code in the browser session, enter the user_code from the response payload.
    3. When the Successful message is displayed, it is recommended to log out of the browser session and close the browser window.
  3. Within 5 minutes of executing the first step of this section and after executing the second step, issue the following request to the Identity Cloud Service URL:

    Linux

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' \
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' \
    --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
    --data-urlencode 'device_code=<DEVICE CODE FROM THE PAYLOAD OF RESPONSE IN FIRST STEP>' \
    --data-urlencode 'client_id=<CLIENT ID OF THE OAUTH2 APPLICATION>'

    Windows Powershell

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' `
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' `
    --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' `
    --data-urlencode 'device_code=<DEVICE CODE FROM THE PAYLOAD OF RESPONSE IN FIRST STEP>' `
    --data-urlencode 'client_id=<CLIENT ID OF THE OAUTH2 APPLICATION>'

    Windows Command Prompt

    curl --location --request POST "https://tenant-base-url/oauth2/v1/token" ^
    --header "Content-Type: application/x-www-form-urlencoded;charset=utf-8" ^
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:device_code" ^
    --data-urlencode "device_code=<DEVICE CODE FROM THE PAYLOAD OF RESPONSE IN FIRST STEP>" ^
    --data-urlencode "client_id=<CLIENT ID OF THE OAUTH2 APPLICATION>"

    Here the value of tenant-base-url is the IDCS URL provided by the Domain Administrator, the device_code value is obtained from the response in Step 1, and client_id is the same client_id used in the first step of this section.

    The response contains the first refresh token:

    {
        "access_token": "eyJ4NXQjUzI.........evRJChXTRfzn6WlCw",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "AQIDBAWF1.....RVkxNCB7djF9NCA="
    }

Secure and Protect the Tokens and Client ID

With OAuth 2, tokens are used instead of user credentials to access resources on Cloud EPM. A refresh token and client ID are used to get a new access token and a new refresh token. Thus, to ensure security of Cloud EPM, it is important to securely encrypt and store the client_id and any tokens. The REST client must securely store the refresh token and client_id.

For EPM Automate, use the encrypt command to create an epw file for OAuth 2.

Step 4: Obtain an Access Token from the Refresh Token

This step is required every time a new access token is required. The REST client uses the latest refresh token and client id to get an access token. It uses the access token as authorization to invoke REST APIs. It also ensures that the latest refresh token and client ID are stored securely.

The REST client uses the Refresh Token grant type to get a new access token and a new refresh token. As mentioned above, this step can be automated. Once automated, it does not require user interaction.

To obtain a valid access token with this grant type, the REST client issues the following request to the IDCS URL:

Linux

curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=<DECRYPTED CLIENT ID OF OAUTH2 APPLICATION FROM SECURE STORE>' \
--data-urlencode 'refresh_token=<DECRYPTED REFRESH TOKEN FROM SECURE STORE>'

Windows Powershell

curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' `
--header 'Content-Type: application/x-www-form-urlencoded' `
--data-urlencode 'grant_type=refresh_token' `
--data-urlencode 'client_id=<DECRYPTED CLIENT ID OF OAUTH2 APPLICATION FROM SECURE STORE>' `
--data-urlencode 'refresh_token=<DECRYPTED REFRESH TOKEN FROM SECURE STORE>'

Windows Command Prompt

curl --location --request POST "https://tenant-base-url/oauth2/v1/token" ^
--header "Content-Type: application/x-www-form-urlencoded" ^
--data-urlencode "grant_type=refresh_token" ^
--data-urlencode "client_id=<DECRYPTED CLIENT ID OF OAUTH2 APPLICATION FROM SECURE STORE>" ^
--data-urlencode "refresh_token=<DECRYPTED REFRESH TOKEN FROM SECURE STORE>"

Here, the value of tenant-base-url is the IDCS URL provided by the Domain Administrator, and the refresh_token and client_id are obtained from the secure store where there were previously stored.

Note: While the client_id and refresh_token are stored securely, it is important that both refresh_token and client_id are decrypted to use in any request. All requests to Oracle IDCS and Cloud EPM are securely transmitted using the https protocol.

Example response:

{
"access_token": "eyJj5M4QjUkI.........abSjZaa86PlseS4lrt7R2",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "AAyyilYBAWD4....FVkxefd8kjoJr6HJPA="
}

The REST client saves the new refresh token for future use (see Secure and Protect the Token and Client ID) and uses the access token as authorization while invoking the REST API (see Use the Access Token).

Use the Access Token

In order to invoke a Cloud EPM REST API, the REST client must provide the access token (obtained in the previous step) in the authorization header as follows:

Authorization: Bearer <access token>

For example, to get the Automated Maintenance Window start time, the client application submits a GET request to this Cloud EPM endpoint /interop/rest/v1/services/dailymaintenance using the access token in the authorization header.

Linux

curl --location --request GET 'https://epm-host/interop/rest/v1/services/dailymaintenance' \
--header 'Authorization: Bearer eyJ5M4QjUkI...abSjZaa86PlseS4lrt7R2'

Windows Powershell

curl --location --request GET 'https://epm-host/interop/rest/v1/services/dailymaintenance' `
--header 'Authorization: Bearer eyJ5M4QjUkI...abSjZaa86PlseS4lrt7R2'

Windows Command Prompt

curl --location --request GET "https://epm-host/interop/rest/v1/services/dailymaintenance" ^
--header "Authorization: Bearer eyJ5M4QjUkI...abSjZaa86PlseS4lrt7R2"

Frequently Asked Questions

What are the default token expiration times?

See Token Expiry Table for the default expiration times for each token type.

A Service Administrator may change these expiration times for an Oracle Cloud Service. To do so, sign in to the identity domain where the service is deployed and update the values on the service’s OAuth configuration page. Exercise caution while extending the token expiration times.

What error is returned when the refresh token has expired?

Executing a refresh token grant flow with an expired refresh token results in a 400 Bad Request response and the following payload:

{  "error": "invalid_grant",
    "error_description": "Token is expired for client : <CLIENT_ID>",
    "ecid": "UsbMB0KCV00000000"
}

Since refresh tokens expire after 7 days, how can scripts that require a valid refresh token operate unattended on intervals longer than 7 days?

Create a job that refreshes the refresh token every 6 days. This is how to do it:

Using EPM Automate:

  1. Use the login command to sign into the environment. Be sure to use the same OAuth2 epw file that you use to run the monthly process.
  2. Use the logout command to exit EPM Automate.

Using REST APIs:

  1. Update the new refresh token for the next job by obtaining an Access Token from the Refresh Token. See Step 4: Obtain an Access Token from the Refresh Token .
  2. Discard the access token.

What error is returned when the refresh token is invalid?

Executing a refresh token grant flow with an invalid refresh token results in a 400 Bad Request response and the following payload:

{  "error": "invalid_grant",
    "error_description": "The given token in the request is invalid",
    "ecid": "UsbMB0KCV00000000"
}

What errors are returned for other issues?

A 400 Bad Request response with the following payloads are returned when there is an error:

Invalid request (for example, not all request parameters are supplied):

{
    "error": "invalid_request",
    "error_description": "The request contains invalid parameters or values"
}

Invalid grant (for example, using a token that has already been used) :

{
    "error": "invalid_grant",
    "error_description": "The token has already been consumed"
}

Invalid scope (for example, providing invalid scope):

{
    "error": "invalid_scope",
    "error_description": "Invalid scope"
}

What error is returned when an invalid or expired access token is provided?

When an invalid or expired access token is provided in a request, the server responds with a 401 Unauthorized response with the following HTML in the payload:

<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr>
</body>
</html>

Can a token be requested with multiple scopes?

Multiple scopes across different resources (Cloud EPM environments) are not supported by Identity Cloud Service. Each token request can support only one resource. Requests for multiple scopes within the same resource are supported with space delimited scopes. Requesting multiple scopes across different resources results in a 400 Bad Request response with the following payload:

{
"error": "invalid_scope",
"error_description": "Invalid scope"
}

Can a valid token received for one Cloud EPM environment be used to access all Cloud EPM environments in the same IDCS domain?

A token can only be used to authorize requests to the environment for which it was issued.

What information is logged in the access log with OAuth?

The access log shows the user name, just as it does with basic authorization. The client ID and access token are not logged.

When using multiple scripts to run EPM REST APIs, the refresh token grant type seems to fail randomly with a message that the token is already consumed. What is the resolution?

Each refresh token is a single use token. After first use, the same token cannot be reused. Trying to use a particular token after it has already been used results in the message, The token is already consumed.

The right way is to set up each script with its own refresh token. To do that, execute the procedure to obtain and save the first refresh token once for each script requiring a refresh token, and then set up each script to use its own refresh token. All scripts can still use the same clientID.