Integrate OAuth 2.0 to access Platform of Trust APIs

Introduction

Using OAuth 2.0 to access Platform of Trust. This guide is meant for developers who want to provide access to Platform of Trust APIs by implementing proper authorization flow for their users. In this guide you will find information on how to build basic authorization flow.

Overview

  1. Get OAuth credentials.
  2. Implement authorization process.

    1. Login endpoint
    2. Exchange token
  3. Summary

Get OAuth credentials

First of all developers must make sure they have OAuth credentials that will be pass to authorization server. To obtain OAuth credentials you have to create OAuth client or register an application. We have described it in Register an application guide. As a result you must have at least following data:

Client ID: cc4a3f95-ad8b-4048-842e-71d6ea810bc9
Client Secret: CQYP75kYXbmUgcKQZYg7q-2f_ndeJ-_9biEsbyLzUXQ
App access tokens: 
[
    {‘id’: ‘98e5c752-1a2b-4c78-b021-2b9e447c75af’, ‘token’: ‘413af71d-4d1e-4bbe-8b12-fe16f723ee9c’},
    {‘id’: ‘197969b8-32e0-47b1-a722-d82052dd5a53’, ‘token’: ‘f097cd95-9943-45e9-9311-159cb54712ca’}
] 

This OAuth 2.0 credentials is required to start implementing authorization flow to Platform of Trust.

Implement authorization process.

Usually developers set up a backend application to communicate with Authorization server. In Platform of Trust, your application will be sending requests to Login portal. The portal will take care of some specific parts of authorization flow. In your application you should have 2 necessary endpoints: login and exchangeToken.

# Routes and API endpoints

GET /login
GET /exchangeToken

The whole process should look like this:

oauth scheme

Login endpoint

/login endpoint's main purpose is to generate uri to Login portal and provide required parameters that will be used by Login portal to authenticate users.

Required parameters are:

grant_type - Must be "authorization"
response_type - Must be "code"
client_id - ID of OAuth application you have gotten in step 1
redirect_uri - Url where users will be redirected to exchangeToken, also done in step 1
cancel_url - Fallback URL in case user decline authorization of your application

Optional parameter:

state - even though state is optional, it is recommended to generate one for each request. Enforce state validation during /exchangeToken to add additional security layer. Read more about state.

Example:

https://login-sandbox.oftrust.net/?grant_type=authorization&response_type=code&redirect_uri=https://world-sandbox.oftrust.net/api/exchangeToken&client_id=f773dafe-20c0-4a25-aa3e-9da0b81b9304&cancel_url=https://world-sandbox.oftrust.net&state=eyJkIjogeyJyIjogImh0dHBzOi8vd29ybGQtc2FuZGJveC5vZnRydXN0Lm5ldC9hcGkvZXhjaGFuZ2VUb2tlbiIsICJ0cyI6IDE1NzE3NDkwMzZ9LCAiaCI6ICIzODc4MTFiYzdkOWRiODEwYTM2Yzk0MmQ0YWMwZTk3MmY1NGQxODBjIn0=

Pseudo code:

state = my_app.generate_state()
auth_uri = my_app.generate_uri(
    grant_type=authorization, 
    response_type=code, 
    client_id=foobar, 
    redirect_uri=foobar.example.com/exachangeToken, 
    cancel_url=foobar.example.com, 
    state=state
)
my_app.redirect(auth_uri)

This uri will redirect a user to Login portal, where authorization flow continues. At some point Login portal will generate an authorization code and redirect the user from Login portal to redirect_uri that you specified in this step. The purpose of it is to exchange the code for an access token and some other data.

Exchange token

This user request due to redirection from Login portal to your redirect_uri, should contain at least following params:

code - authorization code generated by authorization server
subject - is ID of created user, can be used to give oauth client permissions to read your data
client_id - your OAuth application ID, can be used to validate state

Optional:

state - Should be validated. Parameter generated during /login request, optional but recommended to protect against CSRF.

Example:

https://foobar.example.com/exchangeToken?code=35z9T7bBmbtbhRZ6xTF1NFiYnSava3&state=eyJkIjogeyJyIjogImh0dHBzOi8vd29ybGQtc2FuZGJveC5vZnRydXN0Lm5ldC9hcGkvZXhjaGFuZ2VUb2tlbiIsICJ0cyI6IDE1NzE4MTgzNjB9LCAiaCI6ICI2ZDRiNTIxMzlhZjI5MzM4YzJiZGFmY2Q2Y2E1N2QzMjllMjdmODBhIn0%3D&redirect_uri=https%3A%2F%2Ffoorbar.example.com%2FexchangeToken&subject=90dea9db-4515-4640-93dd-a19faba9c9f0&client_id=f773dafe-20c0-4a25-aa3e-9da0b81b9304

But it is not there yet, we still need to provide additional data to Authorization Server

client_secret # OAuth application's secret you recieved in step 1
client_id # OAuth application's id you recieved in step 1 or client_id from initial user exchangeToken request
redirect_uri # redirect uri to validate, must be the same as provided previously in `/login`  
grant_type # Must be "authorization_code"
code # from initial user exchangeToken request 
state # from initial user exchangeToken request

So from your backend you need to send an API request to Login portal.

Example:

curl --request POST \
  --url https://login-sandbox.oftrust.net/api/exchangeToken \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data code=5z9T7bBmbtbhRZ6xTF1NF \
  --data client_id=f773dafe-20c0-4a25-aa3e-9da0b81b9304 \
  --data redirect_uri=https://foorbar.example.com \
  --data grant_type=authorization_code \
  --data state=IxMzlhZjI5MzM4YzJiZGFmY2Q2Y2E1 \
  --data client_secret=ICI2ZDRiNTIxMzlhZjI5MzM4YzJiZGFmY2Q2Y2

With this request you should get following response's data:

{
    'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzY29wZSI6bnVsbCwiZXhwIjoxNTcxOTkxODU5LCJzdWIiOiJlMTUzZTIwMC0xNGQ1LTQzY2UtOTVkYy0yZGIyMmFjNjc2N2YiLCJhdWQiOiJmNzczZGFmZS0yMGMwLTRhMjUtYWEzZS05ZGEwYjgxYjkzMDQiLCJ0eXBlIjoiVXNlciIsImlzcyI6IkxFIiwiaWF0IjoxNTcxOTA1NDU5LjAsInNjb3BlcyI6IiJ9.NvMhYBUsDuO_sVt2Ar5-JOBPNvwOWdH_IO0Du521oXKpb-XMcqMwRCQHr1CYOGhhnwtEeFLuQPKHuNIFPDaObGW3PcGu8Z256O0iATyBlPs5D59Pcnup5Rde3eleOuHPXefSgetqRuRKvFuVvYOSjThC3oxqriRcA9Q271q7sGXSrV5ZhB0FiqdYwEV04Ln-lT8GcgZmfWwptZzV2Kcjy_RZp1f3Olc15UvypL67yBQlNhJk2qTCAiWvcj-xGMPAN-vzHJH7vsoZEiojYZlPAcZmJ8wYnR8Uy6IGEt_wyLCZbjwcfHFPZT7d4EgrvAZKfNO1t5SQowWZ9ID9IqBOgwOXiNCQINgycoTBeapT-38smflpnoYiumbBgX_8gO7XITH_EQQ7RtXOjpA2pajmyOT9m8BWlAfDTqu4FTSzJ__nPbwR4S8PAj5YhjqCJ_DbPTER91CFJByzDP3YYFFqXQND7YZn1EwMpZSSOi0fJ4g7cO7x4CnhD3HAyw9KVVsaM9xsAV7eBYudKbJ2TkBj1br0FidC_6MU68fja9ct2KomEw3fHk2fmvwRlnhKBcYuA-238QWHnMf0bQWuHE_ilWm0NWLFUbLfzpCfjILF38OI-dEeV2MRdpJk1Y7p8fxnZUyTONLYiVOXCttBK1tcmp-B2eFhtQpYchJyEFqANEs',
    'expires_in': 86400,
    'token_type': 'Bearer',
    'state': 'eyJkIjogeyJyIjogImh0dHA6Ly93b3JsZC5sb2NhbDo4MDgwL2FwaS9leGNoYW5nZVRva2VuIiwgInRzIjogMTU3MTkwNTQ0Nn0sICJoIjogImE3NjI3ZDFlN2RkMmM2MzQyNWIyNWJkNDg0YzRmMDI3ZTUxOGZlYzEifQ==',
    'refresh_token': 'XBR0l7f8eWspLlxmrk2UPjSNVX0zuC'
}

Note access_token should be passed with each request that require Authorization to API. You can e.g. store this token to client's cookie with httpOnly and secure flags. Then pass it to any Platform of Trust APIs in Authorization header.

headers['Authorization'] = authorization_toke

Pseudo code:

state = my_app.request.get('state')
code = my_app.request.get('code')

oauth_res = my_app.send_exchange_token_request(state, code, client_secret, client_id,  redirect_uri, grant_type)
my_app.validate_state(oauth_res.state)

bearer_token = f'{oauth_res.token_type} {oauth_res.access_token]}'
my_app.set_cookie('Authorization',
                   bearer_token,
                   max_age=oauth_res.expires_in,
                   httponly=True,
                   secure=True
                   samesite='Strict'
)

my_app.redirect(foo_bar_host) 

Summary

This guide contains bare minimum about how to get access to Platform of Trust APIs via OAuth 2.0.

For detailed documentations on Platform of Trust core APIs, Visit Platform of Trust API Documentation.