How to do seamless sign on (SSO) for integrating SMART app with FHIR compliant EHR

Saurabh Rastogi
Unboxing Product Management
7 min readNov 23, 2020

The first step in building a SMART (Substitutable Medical Applications, Reusable Technologies) application with FHIR (Fast Healthcare Interoperability Resources) compliant EHR (Electronic Health Record) is identifying an authentication and authentication strategy. Fortunately, SMART on FHIR lays down very specific guidelines to do it. It proposes to use OpenID Connect and OAuth 2 for authentic and authorization respectively. If you are building a new application, there is a high probability that it supports OAuth 2 and Open ID Connect. Let’s take a quick look at OpenID Connect and OAuth 2.

OpenID Connect and OAuth 2.0

OAuth 2.0 is a widely used standard for authorization. It helps identify what a user can do in the application. It is very simple and interoperable between web, mobile, and desktop applications.

OAuth 2.0 allows users to use their trusted application as the main identity provider when they authenticate with other applications. A real-life example that you might have experienced is ‘Login through LinkedIn’ or ‘Login through Google’.

Following diagram shows how actions flow through it -

While OAuth 2.0 is used for authorization, OpenID Connect is a layer on top of that for authentication. It helps identifying ‘who’ a user is.

Following parties are central to OAuth 2.0 and Open ID Connect-

Resource owner — Resource owner could be an end-user or a machine if no human interaction is involved in accessing the resource.

Authorization server — At its core, an authorization server is simply an engine for minting OpenID Connect or OAuth 2.0 tokens. Authorization server has its own unique URI.

Resource server — Server where the resource (data) that needs to be accessed is located. In case of integration with FHIR based EMRs, those systems will be the resource server.

Different ways to connect third party SMART apps with EHR

While wiring up authentication and authorization, it’s important to keep in mind the various launch schemes. SMART app’s can be launched in multiple ways. SMART specifications provide a launch framework to connect third-party applications to EHR data. This allows for apps to launch from within the EHR or outside of it as a standalone app.

The Launch Framework supports the uses cases as defined for Phase 1 of the Argonaut Project:

  • Patient apps that launch standalone
  • Patient apps that launch from a portal
  • Provider apps that launch standalone
  • Provider apps that launch from a portal

Launching SMART App from within EHR

Apps can be launched from within the EHR by opening through a preconfigured launch URL into a new browser tab or within an iframe. Context such as patient record, or facility required for appointment manager is passed through URL.

Launching SMART App as standalone app

In this case, the app first goes to the FHIR server of the EHR to get the metadata. Using this metadata app then authorizes the EHR authorization server. Once scopes are identified, the app uses those scopes to get the data (patient or clinical user or any other data specified in FHIR specifications) from the EHR server.

Managing access to the data

SMART on FHIR apps uses OAuth scopes to communicate access requirements with the EHR. Apps that need to read existing data from an EHR should ask for read scopes. Apps that need to write data to an EHR (e.g., FHIR create, update, and delete) should ask for write scopes.

In general, scopes can be used for three kinds of data:

Clinical data: To access the clinical data of patients we have following scopes:

Contextual data: Generally, SMART apps will need a context to provide seamless integration with EHR. E.g.

- Patient record in the EHR

- Encounter in the EHR

- Location (hospital or facility) from where clinical user is logging in

There are two approaches to pass context from EHR to SMART app:

  1. Apps that launch from the EHR: They will be passed an explicit URL parameter called launch. For example — launch=abc123
  2. Standalone apps: Once an app is authorized, the token response will include any context data the app has requested

Identity data: To authenticate and fetch the details or profile information of clinical end-user, “openid” and “fhirUser” OpenID connect scopes should be used.

The Mechanics of Authentication and Authorization

Registering the app in EHR portal

We need to register an app with the EHR to access its FHIR resources, or to use it for authentication or authorization. Most of the EHR’s that support FHIR, provide a portal where we can create the app. We need to provide the following information to the EHR for creating the app.

After the app is registered, the EHR will provide the client_Id which will be a unique identifier of our app registered in the EHR portal.

Authentication workflow and token generation for each of the workflow

Step 1: The client application is launched from the patient portal or EHR

The client app is launched by the EHR with the launch URL of the client application specified in the EHR’s configuration. The EHR sends a launch token and the FHIR server’s endpoint URL (ISS parameter).

launch: This is a token generated by EHR and signifies that an active session already exists. This token is one-time use and will be exchanged for the authorization code.

iss: This parameter contains the authorization server’s FHIR endpoint URL.

Step 2: The client application retrieves the conformance statement

To determine which authorized and token endpoints to use in the EHR launch flow, make a GET request to the URL which is constructed by taking the ‘iss’ provided in the above step and appending /metadata at the end.

Step 3: The client application requests an authorization code from EHR

After getting the launch token from the EHR, make a request to the EHR authorization server on the authorize endpoint. This request will exchange the launch token for an authorization code. Append the following querystring parameters to the request:

response_type: This parameter must contain the value “code” that represents the client application which is requesting authorization code.

client_id: This parameter contains your web application’s client ID issued by EHR.

redirect_uri: This parameter contains your application’s redirect URI. After the request completes on the EHR server, this URI will be called as a callback.

state: It’s useful in case you want to restore the app state after login, since the whole app unloads or unmounts when the OAuth screen opens, and you might need to redirect the user to the right protected URL where they were trying to login.

scope: This parameter describes the information for which the web application is requesting access.

Here’s an example of an authorization request.

https://example.com/oauth2/authorize?response_type=code&redirect_uri=[redirect_uri]&client_id=[client_id]&state=[state]

Step 4: EHR’s authorization server reviews the request

The EHR’s authorization server reviews the request. If the request is approved, the authorization server redirects the browser to the redirect URL supplied in the initial request and appends the following querystring parameter.

code: This parameter contains the authorization code.

state: This parameter will have the same value as the earlier state parameter.

Step 5: Request for access token

After receiving the authorization code, make a POST request to the EHR for the access token on the token endpoint.

The following parameters are required in the POST body:

grant_type: For the EHR launch flow, this should contain the value authorization_code.

code: This parameter contains the authorization code.

redirect_uri: This parameter must contain the same redirect URI that was provided in the initial access request.

client_id: This parameter must contain the application’s client ID issued by EHR that you provided in the initial request.

Here’s an example of what an HTTP POST request for an access token might look like:

POST https://example.com/oauth2/token HTTP/1.1

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=yfNg-rSc1t5O2p6jVAZLyY00uOOte5KM1y3YUx&redirect_uri=https://test.com/test/smart&client_id=d45049c3-3441-40ef-ab4d-b9cd86a17225

The EHR responds to the POST request with a JSON object that includes an access token.

Step 6: Request for patient data

With a valid access token, the client application can now request patient or other protected data from the EHR.

Persisting and refreshing token

Refresh tokens are not typically needed for embedded (SMART on FHIR) launches because users are not required to log in to EHR during the SMART on FHIR launch process, and the access token obtained from the launch process is typically valid for longer than the user needs to use the app.

Conclusion

If you are planning to build a SMART app, implementing FHIR OAuth2 is easy to implement and allows seamless signon. If you want to convert an existing app into a SMART app, even then SSO won’t be a difficult thing to do as long as your app supports OpenID Connect and OAuth2 for authentication and authorization.

I wrote this blog for our Medium Publication- Unboxing Product Management. The publication is a weekly column by people of Quovantis to share their learning.

--

--