Working with OAuth 2.0

Orion Health APIs use the OAuth 2.0 authorization framework for authorizing access to API resources. OAuth 2.0 enables a third-party application to obtain secure and controlled access to, in this case, clinical data stored in the Orion Health data repositories.

The following OAuth 2.0 grant types are supported:

  • Authorization Code
  • Implicit Grant
  • Password Grant
  • Client Credentials

By default, only Authorization Code and Implicit Grant are enabled when an App is registered using the My Apps page. Contact Orion Health if you require access to the other grant types.

This guide will go over the Authorization Code grant type workflow which is the most commonly used grant type for Web and Mobile applications.

Authorization Code Grant Workflow

The OAuth 2.0 Authorization Code Grant workflow can be used by both Web and native mobile applications to obtain an OAuth 2.0 access token that can be used to access Orion Health Open APIs on behalf of a user.

Web applications will have a server-side component where the application's client_secret MUST be kept secret from the client (browser), e.g. it must not ever be returned to the browser in an HTML page or Javascript resource.

Native mobile applications with a server side component should store the client_secret so it is only accessible to the server side component.

Standalone native mobile applicattions that don't have a server side component MUST securely ship the client_secret with the application.

Prerequisites

Before being able to use the Authorization Code Grant workflow you will need the following information:

  1. client_id - the identifier issued to the client/app
  2. client_secret - the secret issued to the client/app
  3. redirect_uri - the URL that the OAuth 2.0 Authorization Server will trigger after a user approves access to the APIs on their behalf
  4. scope - this depends on which Orion Health Open APIs the application intends on using
  5. auth_base_url - the base URL for the OAuth 2.0 APIs, which depends on which instance of Orion Health Platform is being used e.g. for our sandbox instances it is https://auth.orionhealth.io
  6. api_base_url - the base URL for the APIs, which also depends on which Orion Health Platform is being used e.g. for our sandbox instances it is https://api.orionhealth.io

NOTE: The client_id, client_secret, and redirect_uri are all available through the My Apps page for applications registered with the Developer Portal.

Steps to access the Orion Health Open APIs

There are three major steps to the Authorization Code Grant workflow.

1. Open the OAuth Authorization Web Page

Open a new browser window with the following URL.

<auth_base_url>/oauth2/authorize?response_type=code&client_id=<client_id>&scope=<scope>&redirect_uri=<redirect_uri>&state=<state>

The redirect_uri parameter is optional. If provided it MUST exactly match the redirect_uri configured for the application. It MUST also be provided in step 3 if included here.

The state parameter is also optional but strongly recommended to help avoid CSRF exploits. For more information, please refer to the Cross-Site Request Forgery section in the OAuth 2.0 RFC and also The Importance of the state parameter in OAuth2 to help determine the best way to support the state parameter for your particular client and server technologies.

2. User Authorization

The user will be presented a web page where they need to provide their user credentials, typically a username and password, and then approve access for the application to the scope requested.

After the user approves access, the browser window location is changed to the redirect_uri defined for the application. The following query parameters are additionally included:

  • code - the authorization code that is then used to obtain an access token
  • state - only if provided in step 1. The application MUST ensure that the state parameter is the same as originally provided in step 1. If it is not the application must not proceed to the next step.
HTTP/1.1 302 Found
Location: <redirect_uri>?code=sh67fgtadg67fg98aygfh89&state=789456745345 

NOTE: If the redirect_uri endpoint renders an HTML page, any resources on that page will be able to see the authorization code in the URL. For example, Javascript can read the URL directly, and any HTTP requests made from the page may send the URL in the Referer HTTP header. We STRONGLY recommend that the server processes the request and then redirects to another URL that doesn't include the response parameters.

3. Obtaining the Access Token

The server-side component of the web application now needs to exchange the code for an access_token, which can then be used to access the APIs. The client_id and client_secret must be included using the HTTP Basic authentication scheme in an Authorization header.

POST /oauth2/token HTTP/1.1
Host: <auth_base_url>
Authorization: Basic base64(<client_id>:<client_secret>)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=<code>&redirect_uri=<redirect_uri> 

For a successful 200 OK response, the server will reply with a JSON payload containing:

{
  "token_type": "bearer",
  "access_token": "XDvyQic6GCJv7GUTXysfgsfgT3ymMjL",
  "expires_in": 3599,
  "refresh_token": "ZHHT44fsgfgh3YrDoVXDDIXMW9LBequgHQg",
  "scope": "patient/*"
} 

The access_token is used to access Orion Health Open APIs, and the refresh_token can be used to obtain a new access_token when it expires in expires_in seconds.

NOTE: both the access_token and the refresh_token should be considered with similar sensitivity as a password and stored securely by the server-side component. The access_token MUST only be made available to the client application over HTTPS. Where possible the refresh_token SHOULD only be used by the server-side component to refresh the access token.

Accessing Orion Health Open APIs with the Access Token

An application accesses Orion Health Open APIs on behalf of the original authorizing user by providing the access_token as a Bearer Authorization header.

GET /path/to/api HTTP/1.1
Host: <api_base_url>
Authorization: Bearer <access_token> 

Detecting an Expired Access Token

The access_token is only valid for the duration defined by the expires_in property. Relying on the expires_in duration can have challenges due to clock drift between the application server(s) and the OAuth Authorization Server(s). Additionally, it's only accurate to the nearest second.

Orion Health recommends that applications refresh the token when API requests respond with a 400 (Bad Request) HTTP response code with the text invalid_grant as part of an error property within an application/json response:

{
    "error": "invalid_grant"
} 

NOTE: It's important to include the payload check rather than just relying on a 400 response code. There are many other situations where a 400 HTTP response code could result due to other errors with the HTTP request.

Refreshing the Access Token

The refresh_token provided along with the original access_token is used to refresh the access token.

POST /oauth2/token HTTP/1.1
Host: <auth_base_url>
Authorization: Basic base64(<client_id>:<client_secret>)
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=<refresh_token> 

NOTE: the refresh_token can ONLY be used ONCE. An application MUST ensure that only a single thread can update the access token.

Revoking the Access Token

The Orion Health API Manager supports the OAuth 2.0 Token Revocation RFC extension to OAuth 2.0.

The refresh_token is used to revoke access to the application. This MUST be used for any application that supports the concept of "Logout". Only the refresh_token is supported for revocation. The access_token is not supported.

POST /oauth2/revoke HTTP/1.1
Host: <auth_base_url>
Authorization: Basic base64(<client_id>:<client_secret>)
Content-Type: application/x-www-form-urlencoded

token=<refresh_token>