Skip to content

Delegates user authentication to an OAuth 2.0 authentication provider.

Notifications You must be signed in to change notification settings

icrc-loliveira/openmrs-module-oauth2login

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenMRS OAuth 2.0 Login Module

Description

This module delegates user authentication to an OAuth 2.0 resource provider. In effect it turns OpenMRS into an OAuth 2.0 client as soon as the module is installed and running.

Overview

It suffices to install the module for OpenMRS' default authentication scheme to become inactive and for the module custom authentication scheme to take over.

The module consumes a configuration file oauth2.properties that must be dropped in the OpenMRS app data directory:

.
├── modules/
├── openmrs.war
├── openmrs-runtime.properties
├── ...
└── oauth2.properties

The properties configuration contains two separate sets of settings:

  1. The usual OAuth 2 properties:

    • The client ID and secret.
    • A couple of URIs to transact with the OAuth 2 provider: user authorization URI, access token URI and user info URI.
  2. OpenMRS users properties mappings with the OAuth 2 'user info'.
    For new users the master information is first maintained with the OAuth 2 provider, starting with their username. This information is obtained through a JSON response from the user info URI. A simple one-to-one mapping between what is needed from an OpenMRS user's perspective and what is given by the OAuth 2 provider can be provided through the OAuth 2 properties file.

The module ships with sample test resources that show how the OAuth 2 properties file should look like when using JBoss' Keycloak and Google API as OAuth 2 providers, see here.

Authentication Mechanism

Overview

OpenMRS requires persisted OpenMRS users with roles to perform actions within the application. For the OAuth 2 provider to be able to take care of authentication there has to be a duplication of users in both systems. A user will exist both with the OAuth 2 provider and the corresponding user will also exist within OpenMRS *.

The authentication is based on the username.

* This duplication of users could be avoided if OpenMRS was fully leveraging Spring Security. This is not yet the case and as of now authorization is made based on users that are persisted and accessed through the DAO layer.

On-the-fly user creation

However at first the user might not exist yet in OpenMRS and as a convenience the module will create a new OpenMRS user on the fly. This is why a mapping mechanism must exist between the OAuth 2 provider user infos and the OpenMRS users, at minima to find out what the OpenMRS username will be.

Keeping identities in sync with OpenMRS

The main use case is to help support the management of users and roles outside of OpenMRS, with the identity provider. The User pieces of information that are mapped to OpenMRS user properties and that can be updated at each authentication are listed here:

* Username and system ID cannot be updated, they are set once and for all at the first authentication of the user.

Almost externalised role management

A list of OpenMRS roles can be provided through the user info JSON. This can be done through leveraging the openmrs.mapping.user.roles mapping property that holds a pointer to the user info JSON key whose value is a comma-separated list of OpenMRS role names.

For instance a basic user info JSON might look like that:

{
  "sub": "4e3074d6-5e9f-4707-84f1-ccb2aa2ab3bc",
  "email": "[email protected]",
  "roles": "Nurse, Clinical Advisor"
}

With an OAuth 2 properties mapping set as such:

openmrs.mapping.user.roles=roles

Where "Nurse" and "Clinical Advisor" are expected to be OpenMRS role names. Those role names are then used to fetch OpenMRS roles to be assigned to the user. All the role names that do not point to existing OpenMRS roles are skipped.

This requires using an identity provider that allows the configuration of the user info JSON with custom members, such as this "roles" member in the above example.

Sample mapping

Let us start from a sample JSON to understand how the mappings should be set.

1) Sample user info JSON:
{
  "sub": "4e3074d6-5e9f-4707-84f1-ccb2aa2ab3bc",
  "preferred_username": "tatkins",
  "given_name": "Tommy",
  "family_name": "Atkins",
  "email": "[email protected]",
  "roles": "Provider, Nurse"
}
2) Corresponding mappings needed in oauth2.properties:
openmrs.mapping.user.systemId=sub
openmrs.mapping.user.username=preferred_username
openmrs.mapping.person.givenName=given_name
openmrs.mapping.person.familyName=family_name
openmrs.mapping.user.email=email
openmrs.mapping.user.roles=roles

Example

If a user authenticates as 'jdoe' with the OAuth 2 provider, OpenMRS will attempt to fetch the user 'jdoe'.

  • If a 'jdoe' user can be found in OpenMRS, then it will become the authenticated user.
  • If a 'jdoe' user cannot be found in OpenMRS, it will be created with a initial set of roles and will become the authenticated user.

Redirect URL after successful login

By default the user will be redirected to the root URL / after a successul login. The redirect URL can be modified by using the global property (GP) oauth2login.redirectUriAfterLogin. For example when the module is used within the Reference Application with the two-screen login enabled, this GP can be used to enforce a redirect to the login GSP page (hence kicking in its Java controller logic):

/referenceapplication/login.page?redirectUrl=/index.html

Two-step login with OpenMRS 2.x

In OpenMRS 2.x it is necessary to explicitely enable the two-step login for the OAuth2 delegated authentication to work properly. To do so make sure that the following global property exists with a non-blank value: referenceapplication.locationUserPropertyName.

Configuration Guides

  1. Guide for Keycloak
  2. Guide for Google API

Requirements

OpenMRS Core 2.2.1 or Core 2.3.0 and above.

About

Delegates user authentication to an OAuth 2.0 authentication provider.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%