Configuring OAuth2 authentication for REST API

Table of contents

Get access to the API

After a successful CustomerID installation or upgrade eIDM Services site has CustomerID API application visible in SSO Management UI.  The API is accessible using OAuth2 to a group named CustomerID API Users. In order to access the API, a new OAuth2 application must be created and an API user needs to be defined. The following steps will guide you through these steps.

Do not use CustomerID API application client credentials

Do not use or expose the ready-made CustomerID API application ID and secret to integrate with the API. The CustomerID API application client credentials are meant for internal use between CustomerID REST API and SSO

Creating a new OAuth2 application

Create new OAuth2 client application as instructed in Management UI Applications or alternatively use the Management API. Allow CustomerID API Users to access the newly created application and enable for example password.2 method or your preferred method for the application.

The following OAuth2 client metadata describes a simple OAuth2 client that can request an access token using OAuth2 Resource Owner Password Credentials Grant.

{
  "client_id": "... redacted ...",
  "client_secret": "..redacted..."
}

After the application has been configured proceed with defining an API user.

Define API user

Add a user to CustomerID API Users group e.g. with the Management UI. You can choose from the following options:

  • Create a new user with password.2 method allowed, and add it
  • Add an existing user with password.2 method allowed
  • Add an existing group

Any of these actions can also be performed using the Management API

Locate API scope

In order to access the CustomerID API you need its client ID for the scope parameter of the OAuth2 Token Request. This client ID has been defined in your linux/win32.config file with setting: rest.oauth2.client.uuid and is visible in eIDM Services → Applications → CustomerID API as depicted here

Figure 1 The system internal CustomerID API client ID

Add SSO server certificate to Java trust store

When using OAuth2 access token CustomerID API connects to the SSO OAuth 2.0 endpoints, so the server certificate of those endpoints must be trusted by the Java Runtime Environment used by CustomerID. By default, no publicly issued CAs are trusted and must be trusted explicitly.

Follow these steps on each CustomerID node by applying the instructions from here:  Add Server Certificate to Java Trust Store - SSO

  • When SSO is installed on different server than CustomerID copy the SSO certificate file to the CustomerID server
  • Add certificate to Java trust store and
  • Restart CustomerID i.e. WildFly

Verify the API works

The following examples use the REQ003 List Organizations API call documented in REST API 2.0 - CustomerID.

Test the connection

You can start testing the connection using curl. You may use the --insecure flag in case self-signed certificates are used:

$ curl --request GET 'https://<customerid-base-url>/customerid-rest/services/2.0/organizations?technicalName=not-found'

An HTTP 401 status code is expected as no OAuth2 access token was provided in the request. The response will contain WWW-Authenticate header with the required scope for the SSO OAuth2 token endpoint.

Get the access token

Different SSO endpoints for OAuth2 and how to find them are explained in OAuth 2.0 and OpenID Connect metadata.

Get the access token e.g. with OAuth2 Password grant:

$ curl \
  --request POST 'https://<sso-base-url>/uas/oauth2/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=password' \
  --data-urlencode 'scope=openid <customerid-api-client-id>' \
  --data-urlencode 'client_id=<oauth2-client-id>' \
  --data-urlencode 'client_secret=<oauth2-client-secret>' \
  --data-urlencode 'username=<customerid-api-user>' \
  --data-urlencode 'password=<customerid-api-password>'

Where

ParameterDescription
customerid-api-client-id
Is the client_id of the CustomerID API retrieved in Locate API scope section
oauth2-client-id
Is the client_id of your OAuth2 client application you created in Creating a new OAuth2 application section
oauth2-client-secret
Is the client_secret of your OAuth2 client application you created in Creating a new OAuth2 application section
customerid-api-user
Is the username of the user you created in Define API user section
customerid-api-user-password
Is the password of the user you created in Define API user section

Use the access token

Take the access token from the response and use in the CustomerID API request:

$ curl \
  --request PUT 'https://<customerid-base-url>/customerid-rest/services/2.0/organizations?technicalName=not-found' \
  --header 'Authorization: Bearer <your access token here>'

As a valid OAuth2 access token was provided, the expected status code is HTTP 200 with a similar response body:

Response
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Organizations xmlns="http://schema.ubisecure.com/customerid/api" inResponseTo="/2.0/organizations/" method="GET"/>

This indicates that the request was authorized and it returned an empty list of organization IDs assuming there is no organization with the technical name not-found.

Troubleshooting

eIDM Services → Applications → CustomerID API application not found

You have not imported the new versions of customerid.ldif and customerid-secrets.ldif including OAuth2 entries to the LDAP repository.  

Check that you have proper settings in linux/win32.config for the following properties:

rest.oauth2.client.uuid
rest.oauth2.client.secret
rest.oauth2.introspection.url

and if you change the client credentials rerun setup script and restart CustomerID i.e. WildFly first before importing the LDIF files.

OAuth2 authentication challenge is not returned when accessing API without access token

If in step Test the connection HTTP 403 is returned instead of the expected HTTP 401 with the following error response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<error>
    <code>2</code>
    <message>Invalid credentials</message>
</error>

OAuth2 authentication is not enabled in your CustomerID configuration.

Check that you have proper settings in linux/win32.config for the following properties:

rest.oauth2.client.uuid
rest.oauth2.client.secret
rest.oauth2.introspection.url

rerun setup script and restart CustomerID i.e. WildFly. If you changed the client credentials you need to import customerid-secrets.ldif again to the LDAP repository.

Getting access token fails

If in step Get the access token HTTP 400 is returned instead of the expected HTTP 200 with the following error response:

{
    "error_description": "Client is invalid",
    "error": "unauthorized_client"
}

you have forgotten to enable the appropriate password method in step Creating a new OAuth2 application.

Tick from the SSO Management UI for the OAuth2 application you created e.g. password.2 method and click Update on below of the screen.

Figure 2. Enabling password method for the OAuth2 application

Using access token fails

If in step Use the access token HTTP 500 is returned instead of the expected HTTP 200 with the following error response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<error>
    <code>6</code>
    <message>Token validation failed</message>
</error

the token introspection URL rest.oauth2.introspection.url you have specified in linux/win32.config is not valid. Do the following:

  • Check you have completed step Add SSO server certificate to Java trust store on each CustomerID node
  • Check the proper SSO token endpoint URL e.g. from the SSO metadata response
  • Specify rest.oauth2.introspection.url in linux/win32.config accordingly
  • Rerun the setup script and
  • Restart CustomerID i.e. WildFly