Securing Outbound RESTful Service Invocations Using OAuth2

This part of the documentation lists in what way Oracle Health Insurance applications provide support for OAuth2. A thorough understanding of OAuth standards is assumed as a prerequisite for further reading, that is, this guide does not provide an introduction into OAuth.

OAuth2 Use Cases Supported by Oracle Health Insurance Applications

For Oracle Health Insurance applications, the following OAuth2 related use cases are supported:

  1. A RESTful service client in one Oracle Health Insurance application interacting with an OAuth2 secured RESTful service in another Oracle Health Insurance application. Examples of this are:

    • Enrollment: Oracle Health Insurance Claims (the client) sending an enrollment request to Policies (the server).

    • Data Replication: Oracle Health Insurance Authorizations (the client) retrieving member change events from Policies (the server).

    These use cases are supported using the OAuth2 Client Credentials grant type (grant_type=client_credentials).

  2. In Oracle Health Insurance applications, customers can configure REST clients to call external RESTful services. The use of these REST clients and handling responses is scripted by customers in Groovy logic that is executed by Oracle Health Insurance applications. Oracle Health Insurance applications support all OAuth2 related configurations for these customer-configurable clients.

    These use cases are also supported using the OAuth2 Client Credentials grant type (grant_type=client_credentials).

  3. A lightweight UI that executes entirely inside a web browser. One example of this is an Oracle JET-based JavaScript UI as is under construction for Oracle Health Insurance applications. Another example is a custom client built by customers. Support for this use case is outlined in a separate chapter.

Configuration Example: Data Replication - Oracle Health Insurance Authorizations Retrieving Member Change Events from Policies

In this scenario Oracle Health Insurance Authorizations is configured to retrieve Member changes from Policies (Data Replication). The Policies RESTful services are "OAuth secured". The example makes use of the following components:

  • An OAuth2 Authorization Server, for example, as provided by the Oracle Identity Cloud Service (IDCS) or Oracle Access Manager (OAM).

  • Policies is deployed in a separate WebLogic domain. The Policies RESTful services require the use of a valid OAuth bearer or access token.

  • Oracle Health Insurance Authorizations is also deployed in a separate WebLogic domain. The Oracle Health Insurance Authorizations REST clients that access Policies RESTful services are configured to call OAuth secured services.

1. Configure the OAuth2 Authorization Server and Register Client Applications

Setting up a specific OAuth2 Authorization Server is beyond the scope of this guide. See the OAuth2 Authorization Server’s product documentation for that.

Before a client application can request access to resources on a resource server, the client application must first register with the OAuth2 Authorization Service as an OAuth client. For the Data Replication mechanism, three clients are registered with the OAuth2 Authorization Server:

  • one used by the Authorizations application for retrieving change events and

  • another one used by the Authorizations application for retrieving entities and

  • a third one used by the Policies application to validate or introspect an access token

For this example, the following an OAuth Client applications are registered:

Attribute Value

Person Events Client Id

Specify a client id that is unique within the context of the OAuth2 Authorization Server, for example, "AuthsDataReplicationPersonEvents"

Person Events Client Secret

Specify a secret or choose to generate one, for example, "2576ce9b-88e7-44bf-96f1-5cb5e5412323"

Person Entities Client Id

Specify a client id that is unique within the context of the OAuth2 Authorization Server, for example, "AuthsDataReplicationPersonEntities"

Person Entities Client Secret

Specify a secret or choose to generate one, for example, "0ab1fcb1-4f0f-4874-a08f-f7fdfe31d8a1"

Policies Access Token introspection Client Id

Specify a client id that is unique within the context of the OAuth2 Authorization Server, for example, "PolDataReplicationTokenIntrospection".

Note that some OAuth2 Authorization Servers require specific privileges to be set to allow introspection. Make sure that the introspection feature for this client application is enabled.

Policies Access Token introspection Secret

Specify a secret or choose to generate one, for example, "3de4fgf1-6m7j-6543-a08f-f7fdfe31d8a1"

Make sure that the Client Credentials grant type is supported.

2. Verify the OAuth2 Authorization Server Setup and Successful Return of an Access Token

Base64 encode the clientId and clientSecret for a Basic Authentication Authorization header. Base64Encode(AuthsDataReplicationPersonEvents:2576ce9b-88e7-44bf-96f1-5cb5e5412323) and execute a curl command like the following to validate that the OAuth2 Authorization Server returns an access token:

curl -i -H 'Authorization: Basic QXV0aHNEYXRhUmVwbGljYXRpb25QZXJzb25FdmVudHM6MjU3NmNlOWItODhlNy00NGJmLTk2ZjEtNWNiNWU1NDEyMzIz' \
-H 'ContentType: x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'scope=urn:opc:idm:__myscopes__' \
--request POST 'https://host:port/oauth2/v1/token'

The OAuth2 server responds with a JWT access token, for example:

HTTP/1.1 200 OK
Date: Thu, 26 Oct 2017 18:04:15 GMT
Content-Type: application/json;charset=UTF-8
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubdomains;

{"access_token":"eyJhbGciOiJSUzI1NiIsInR ..."
,"token_type":"Bearer"
,"expires_in":3600
}

3. Configure Policies to Secure Its Resources Using OAuth

In case the Policies application receives requests that have an Authorization HTTP header containing an OAuth2 bearer token, it needs to be able validate these tokens. In this example, token introspection according to the RFC 7662 standard are configured. To do that, set the following system properties for Policies:

ohi.oauth.token.validation.method=OAUTH2_ENDPOINT
ohi.oauth.token.introspection.endpoint.url=https://host:port/oauth2/v1/introspect
ohi.oauth.token.introspection.endpoint.client_id=PolDataReplicationTokenIntrospection

This instructs Policies to validate the token using the RFC 7662 compliant introspection endpoint that the OAuth2 Authorization Server exposes. The call to the introspection endpoint is secured using Basic Authentication. The key to the Basic Authentication credentials is specified as a value for the "ohi.oauth.token.introspection.endpoint.client_id" property. The password needs to be configured in the Policies credential store by sending a PUT request like the following to the "/api/credentials/credential/PolDataReplicationTokenIntrospection" resource:

{"username": "PolDataReplicationTokenIntrospection",
 "password": "3de4fgf1-6m7j-6543-a08f-f7fdfe31d8a1"
}

When the OAuth2 Authorization Server introspects the token, it not only verifies that it is still valid (and not expired) but it also returns the user or subject (claim "sub" in the JWT token) for which the token was created. These subjects need to be provisioned as users in the Policies application, and they need to be properly authorized or granted the correct access role.

4. Configure the REST Client in Oracle Health Insurance Authorizations So It Supports OAuth-Secured Services

For Data Replication, two REST requests are used: request DataReplicationPersonEvents to inquire about Person-related change events in the source system (Policies in this case) and request DataReplicationPersonEntities to retrieve the changed Person entities data. The default security feature for this is Basic Authentication.

To specify that Oracle Health Insurance Authorizations calls these OAuth secured Policies resources with a proper OAuth access token set the following properties:

ohi.service.DataReplicationPersonEvents.client.authentication=OAuth
ohi.service.DataReplicationPersonEntities.client.authentication=OAuth

Next, configure the REST clients in Oracle Health Insurance Authorizations so that an OAuth Access Token can be obtained using the OAuth Client Credentials grant type. For the DataReplicationPersonEvents client POST, a request with the following JSON payload to the Oracle Health Insurance Authorizations "/api/generic/oauthclientcredentialsgrantconfigurations" resource:

{ "restClientId": "DataReplicationPersonEvents",
  "clientId": "AuthsDataReplicationPersonEvents",
  "tokenURI": "https://host:port/oauth2/v1/token",
  "scope": "urn:opc:idm:__myscopes__"
}

For the DataReplicationPersonEvents client, set the client secret by PUTting the following payload to the Oracle Health Insurance application’s "/api/oauthclientconfigurations/{id}/setclientsecret" resource:

{ "clientSecret": "2576ce9b-88e7-44bf-96f1-5cb5e5412323"
}

with headers:

Accept = application/json
Content-Type = application/json

{id} is the ID of the DataReplicationPersonEvents client. It is possible to reset client secret for the DataReplicationPersonEvents client using the same URL and payload structure mentioned above.

And for the DataReplicationPersonEntities client POST a request with the following JSON payload to the Oracle Health Insurance Authorizations "/api/generic/oauthclientcredentialsgrantconfigurations" resource:

{ "restClientId": "DataReplicationPersonEntities",
  "clientId": "AuthsDataReplicationPersonEntities",
  "tokenURI": "https://host:port/oauth2/v1/token",
  "scope": "urn:opc:idm:__myscopes__"
}

For the DataReplicationPersonEntities client, set the client secret by PUTting the following payload to the Oracle Health Insurance application’s "/api/oauthclientconfigurations/{id}/setclientsecret" resource:

{ "clientSecret": "0ab1fcb1-4f0f-4874-a08f-f7fdfe31d8a1"
}

with headers:

Accept = application/json
Content-Type = application/json

{id} is the ID of the DataReplicationPersonEntities client. It is possible to reset client secret for the DataReplicationPersonEntities client using the same URL and payload structure mentioned above.

The Oracle Health Insurance configuration is environment-specific. It needs to be repeated for separate instances of Oracle Health Insurance applications and per WebLogic domain.

Configuration Example: Configure a Callout Rule in Policies

In this example, a Callout Rule is defined in Policies for calling an OAuth secured RESTful service in an external application. For Callout Rules, OAuth2 access tokens can be obtained using the Client Credentials grant type. Therefore, the configuration is very similar to the configuration that was outlined in the previous example.

1. Create the Callout Rule Using Dynamic Logic

Define the Callout Rule Dynamic Logic and save it in the application.

// Invoke the Callout request
Object response = initCallOut(WebTarget.class)
                 .path("additional_path_parameters")
                 .request()
                 .buildGet()
                 .invoke()

// Handle the response
if (response.getStatus() == 200 || response.getStatus() == 201) {
  def message = new groovy.json.JsonSlurper().parse(response.readEntity(String.class))
  policy.SOME_DYNAMIC_FIELD = message.SOME_FIELD_VALUE
} else {
  throw new RuntimeException("Unexpected response received")
}

For this example, the Dynamic Logic is saved with the uniquely identifying code 'SAMPLE_CALLOUT_RULE'.

2. OAuth2 Authorization Server Setup

Register a client application with the OAuth2 Authorization Server and make sure it is set up to support the Client Credentials grant type. Verify that the OAuth2 Authorization Server returns an access token when its token endpoint is accessed for the configured client. For reference, see steps 2 and 3 of the previous example.

3. Configure the REST Client in Policies So It Supports OAuth-Secured Services

To specify that the resource that is invoked using the SAMPLE_CALLOUT_RULE Dynamic Logic is secured using OAuth, set the following properties:

ohi.service.SAMPLE_CALLOUT_RULE.client.authentication=OAuth

Next, configure the REST client for this Callout rule so that an OAuth access token can be obtained using the OAuth Client Credentials grant type. For that purpose, POST a request with the following JSON payload to the Policies "/api/generic/oauthclientcredentialsgrantconfigurations" resource:

{ "restClientId": "SAMPLE_CALLOUT_RULE",
  "clientId": "aConfiguredAndUniqueClientId",
  "expirationPeriod": "3600",
  "tokenURI": "https://host:port/oauth2/v1/token",
  "scope": "urn:opc:idm:__myscopes__"
}

For the REST client for this Callout rule, set the client secret by PUTting the following payload to the Oracle Health Insurance application’s "/api/oauthclientconfigurations/{id}/setclientsecret" resource:

{ "clientSecret": "aConfiguredClientSecret"
}

with headers:

Accept = application/json
Content-Type = application/json

Where {id} is the ID of the REST client for this Callout rule. It is possible to reset client secret for the REST client for this Callout rule using the same URL and payload structure mentioned above.