OAuth2 module - for Client Developers

Creating and Managing Clients

See the REST Controller here

Obtaining Tokens

1. Authorization Code Grant Type

Protocol Flow

The OAuth2 specification states the following workflow.

Authorization Code Flow

Fig :  Authorization Code Flow

Here, as usual, the client is the external application. The authorization server is the OAuth2 module. The user agent is the browser being used by the resource owner( end-user).

A)     The client initiates the flow by directing the browser to the authorization endpoint i.e to the OAuth2 module’s authorization controller in the omod layer. The client specifies its client identifier, requested scope, local state and a redirection URI in the request

B)      The OAuth2 module will authenticate the end-user (via browser/user-agent). The OAuth2 module will then ask the end-user if he/she authorizes the client to act on their behalf.

C)      Assuming the access is granted to the client, the OAuth2 module generates a authentication code and stores it in the database. It then redirects to the redirection URI it received in Part A after appending the authorization code and the local state request parameters.

D)     The client sends a request to obtain an access token from the OAuth2 module and includes the authorization code received in the step C. The client should include the redirection URI used to obtain authorization code for verification. The OAuth2 module will first authenticate the client based on the strategy discussed in the Client Authentication section above.

E) The Oauth2 module authenticates the client, validates the authorization code, and ensures that the redirection URI of step D matches step C. If valid, the OAuth2 module will generate an access token and/ or a refresh token

Authorization Request

Authorization Endpoint : GET /ws/oauth/authorize

Request Structure : 

 

Parameter

Required

Description

response_type

REQUIRED

Value = “code”

client_id

REQUIRED

Obtained during Client Registration

redirect_uri

REQUIRED

The redirection endpoint provided during Client Registration

scope

OPTIONAL

The scope of the request (Read/Write)

state

RECOMMENDED

To be used by client to maintain state between request and callback.

Demo Authorization Request localhost:8080/openmrs/ws/oauth/authorize?response_type=code&client_id=test&redirect_uri=www.sanatt.me

Authorization Response

The OAuth2 module redirects the user to the refirectionURI specified during client registration and appends the following parameters in the response's query string : 

Parameter

Required

Description

code

REQUIRED

The authorization code generated by OAuth2 module.Expires in 10 minutes. Therefore make sure you send an access token request within this time frame

state

REQUIRED

If the state parameter is present in the request, it is appended.

Demo Authorization Response www.sanatt.me?code=teVyMz

Access Token Request

Access Token Endpoint : GET /ws/oauth/token

Request Structure

Parameter

Required

Description

grant_type

REQUIRED

Value = “authorization_code”

code

REQUIRED

The authorization code received from OAuth2 module

redirect_uri

REQUIRED

If the “redirect_uri” parameter was included in the authorization request, their value must be identitcal

client_id

REQUIRED

The client_ID given to client during Client Registration process

Demo Token Request http://localhost:8080/openmrs/ws/oauth/token?grant_type=authorization_code&code=teVyMz&redirect_uri=www.sanatt.me&client_id=test

Access Token Response

The response to the access token request is a JSON object containing the access token plus some more information.

PropertyValue
access_tokenthe access_token issued by the OAuth2 module
token_typebearer. OAuth2 module uses bearer tokens. So any request that 'bears' this token will be allowed to access the protected resource
expires_innumber of seconds after which token will become invalid
refresh_tokenuse this to get a fresh access token when the current access token has expired. (see the section on refresh token for details)

 

Demo Access Token Response :

 

OAuth2 Access Token Response body (JSON)
{
    "access_token": "68b245ef-89ba-4d8d-a31a-bb500aa60c6b",
    "token_type": "bearer",
    "refresh_token": "cc2cd01b-962a-4afe-962f-903e46647dd7",
    "expires_in": 599,
    "scope": "read write"
}

 

2. Implicit Grant Type

Protocol Flow

implicit grant flow

Fig : Implicit Grant Flow

A)     The client sends a request to the authorization endpoint of the OAuth2 module. The client includes its client identifier, requested scope, local state and redirection URI.

B)      The OAuth2 module authenticates the user (resource owner) and establishes whether the end-usergrants or denies client’s access request.

C)      Assuming access is granted, OAuth2 module generates a token , and includes it in the URI fragment of the redirection URI specified in Step A.

D,E,F)     The user-agent retains the fragment information locally and processes the response to extract the access token

G)     The user-agent(browser) passes the access token to the client.

Authorization Request

Authorization Endpoint : GET /ws/oauth/authorize

Request Parameter Structure

Parameter

Required

Description

response_type

REQUIRED

Value = “token

client_id

REQUIRED

Obtained during Client Registration

redirect_uri

OPTIONAL

The redirection endpoint registered by the client

scope

OPTIONAL

The scope of the request (see Client Registration)

state

RECOMMENDED

To be used by client to maintain state between request and callback.

Demo Authorization Requesthttp://localhost:8080/openmrs/ws/oauth/authorize?response_type=token&client_id=test&redirect_uri=www.sanatt.me

Access Token Response

When the client gets authorized by the end-user, the OAuth2 module will generate an access token and include the following parameters to the fragment component of the redirection URI

Parameter

Required

Description

access_type

REQUIRED

The access token issued by the OAuth2 module

token_type

REQUIRED

"bearer"

expires_in

RECOMMENDED

The lifetime in seconds of access token.

scope

OPTIONAL

The scope of the request (Read/Write)

state

RECOMMENDED

To be used by client to maintain state between request and callback.

NOTE : As per specification, the OAuth2 module will not generate a refresh token for implicit grant type.

Demo Access Token Response : www.sanatt.me#access_token=68b245ef-89ba-4d8d-a31a-bb500aa60c6b&token_type=bearer&expires_in=432&scope=read%20write

3. Resource Owner Password Credentials Grant Type

Protocol Flow

This grant type is suitable when the resource owner (patient/doctor/ OpenMRS user etc) has a trust relationship with the client. As per specification, this grant type should be allowed only when other grant types are not available

Resource Owner Password Credential

Fig : Resource Owner Password Credential Flow

    1. A)     The end-user/resource owner provides the client with its username and password for the OpenMRS installation.
    2. B)      The client requests an access token OAuth2 module running on the OpenMRS installation through its token endpoint.  The OAuth2 module authenticates the client as well.
    3. C)      The OAuth2 module authenticates the client and validates the end-user’s credentials, and if valid, it issues an access token.

Access Token Request

Token Endpoint : GET /ws/oauth/token

Request Parameter Structure

The client needs to add the following parameters to the request made to the token endpoint.

Parameter

Required

Description

grant_type

REQUIRED

Value = “password”

username

REQUIRED

The end-user’s username

password

REQUIRED

The end-user’s password

scope

OPTIONAL

The scope requested by the client

 

Demo Access Token Request : GET http://localhost:8080/openmrs/ws/oauth/token?grant_type=password&username=admin&password=Admin123&client_id=test

Access Token Response

The response is a JSON object similar to the one shown in Authorization Code Grant Type's access token response.

4. Client Credentials Grant Type

Protocol Flow

The client can request access token using only client credentials to request access to OpenMRS modules and resources for which the client has permissions.

Client credentials flow

Fig : Client credentials flow

A)     The client authenticates with the OAuth2 module and requests an access token from the token endpoint.

B)      If the client authentication succeeds, OAuth2 module will generate a token and send it to client.

Access Token Request

Token Endpoint: GET /ws/oauth2/token*

Parameter

Required

Desciption

grant_type

REQUIRED

Value = “client_credentials”

scope

OPTIONAL

The scope requested by the token

 

* Add the client_id and client_secret as Basic authorization headers

Access Token Response

If the access token request is valid and authorized, the OAuth2 module will issue the access token and redirect to the redirection uri specified during client registration. The HTTP response to the client is exactly similar to those in Authorization Code grant type and Resource Owner Password Credentials grant type.

 

Refreshing Tokens

Once the validity period of access tokens is over, you will have to generate a new access token by using any of the above mentioned grant types or you can swap the expired access token with a new one by using the refresh token that was issued along with the access token.

You need to make a request to the Token Endpoint and include the refresh_token as the request parameter

URI : GET /ws/oauth/token

Request Parameters

ParameterRequiredDescription
grant_typeREQUIRED"refresh_token"
access_tokenREQUIREDthe access token that has expired
refresh_tokenREQUIREDthe refresh_token that was issued along with the access token

 

Demo Request

http://localhost:8080/openmrs/ws/oauth/token&grant_type=refresh_token&access_token=2YotnFZFEjr1zCsicMWpAA&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

Demo Response 

The response will include a JSON object containing the new access token, token type, expiry time and refresh token as shown in the Access Token Reponse for Authorization Code Grant Type.

Retrieving Protected Resources

If you try to access the OAuth2 protected resources without an access token, an 401 Unauthorized response code will be returned.

After obtaining an access token, it can be used to access the protected resources by including the access token in the Authorization Header or as an request parameter while requesting the protected resource.

The OAuth2 module will intercept this request and validate the token and allow access to the protected resource if the token passes validation 

Sample Request

http://localhost:8080/openmrs/ws/fhir/Location/8d6c993e-c2cc-11de-8d13-0010c6dffd0f&access_token=2YotnFZFEjr1zCsicMWpAA

Or

http://localhost:8080/openmrs/ws/fhir/Location/8d6c993e-c2cc-11de-8d13-0010c6dffd0f&

Request HeaderValue
AuthorizationBearer fc49c67e-6932-4846-a4f9-e9a23822da1f