OAuth2 Login - OpenBankProject/OBP-API GitHub Wiki

Introduction

OAuth 2 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, in this case any OBP REST call. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account. OAuth 2 provides authorization flows for web and desktop applications, and mobile devices.

OAuth2 Roles

  • Resource Owner
  • Client
  • Resource Server
  • Authorization Server

Resource Owner: User

The resource owner is the user who authorizes an application to access their account. The application's access to the user's account is limited to the "scope" of the authorization granted (e.g. openid).

Authorization Server: API

The authorization server verifies the identity of the user then issues access tokens to the application. E.g. MITREid Connect

Resource Server: API

The resource server hosts the protected user resources. E.g. OBP-API

Client: Application

The client is the application that wants to access the user's resource. In order to do that, it must be authorized by the user, and the authorization must be validated by the Authorization Server: API.

Authorization Grant

OAuth 2 defines four grant types, each of which is useful in different cases:

  • Authorization Code: used with server-side Applications
  • Implicit: used with Mobile Apps or Web Applications (applications that run on the user's device)
  • Resource Owner Password Credentials: used with trusted Applications, such as those owned by the service itself
  • Client Credentials: used with Applications API access

OBP-API supports at the moment only Authorization Code

Authorization Server: API

Grant Type: Authorization Code

Step 1: Authorization Code Link

http://localhost:8080/openid-connect-server-webapp/authorize?response_type=code&client_id=client&redirect_uri=https://openbankproject.com/&scope=openid

Here is an explanation of the link components:

  • http://localhost:8080/openid-connect-server-webapp/authorize: the API authorization endpoint
  • client_id=client_id: the application's client ID (how the API identifies the application)
  • redirect_uri=CALLBACK_URL: where the service redirects the user-agent after an authorization code is granted
  • response_type=code: specifies that your application is requesting an authorization code grant
  • scope=openid: specifies the level of access that the application is requesting

Note:

  • To get the id token, you have to include the openid scope.
  • To get both the id token and refresh token, you have to include both the openid and offline_access scopes in the request. ...&scope=openid offline_access

Available scopes:

  • openid
  • profile
  • email
  • address
  • phone
  • offline_access

Step 2: User Authorizes Application

screenshot from 2018-02-24 21-20-09

Step 3: Application Receives Authorization Code

If the user clicks "Authorize Application", the service redirects the user-agent to the application redirect URI, which was specified during the client registration, along with an authorization code.

https://openbankproject.com/?code=AUTHORIZATION_CODE

The redirect would look something like this: https://openbankproject.com/?code=htm4zN

Step 4: Application Requests Access Token

The application requests an access token from the API, by passing the authorization code along with authentication details, including the client secret, to the API token endpoint.

http://localhost:8080/openid-connect-server-webapp/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

E.g. : curl -i -X POST "http://localhost:8080/openid-connect-server-webapp/token?client_id=client&client_secret=1234&grant_type=authorization_code&code=gHOPDa&redirect_uri=https://openbankproject.com/"

Step 5: Application Receives Access Token

If the authorization is valid, the API will send a response containing the access token to the application. The entire response will look something like this:

{
  "access_token": "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF6cCI6ImNsaWVudCIsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJleHAiOjE1MTk1MDMxODAsImlhdCI6MTUxOTQ5OTU4MCwianRpIjoiMmFmZjNhNGMtZjY5Zi00ZWM1LWE2MzEtYWUzMGYyYzQ4MjZiIn0.NwlK2EJKutaybB4YyEhuwb231ZNkD-BEwhScadcWWn8PFftjVyjqjD5_BwSiWHHa_QaESNPdZugAnF4I2DxtXmpir_x2fB2ch888AzXw6CgTT482I16m1jpL-2iSlQk1D-ZW6fJ2Qemdi3x2V13Xgt9PBvk5CsUukJ8SSqTPbSNNER9Nq2dlS-qQfg61TzhPkuuXDlmCQ3b8QHgUf6UnCfee1jRaohHQoCvJJJubmUI3dY0Df1ynTodTTZm4J1TV6Wp6ZhsPkQVmdBAUsE5kIFqADaE179lldh86-97bVHGU5a4aTYRRKoTPDltt1NvY5XJrjLCgZH8AEW7mOHz9mw",
  "token_type": "Bearer",
  "expires_in": 3599,
  "scope": "openid"
}

Resource Server: API

Step 6: Configure OBP API to accept OAuth2 Login.

# -- OAuth 2 --------------------------------------------------------------------
# Enable/Disable OAuth 2 workflow at a server instance
# In case isn't defined default value is false
# allow_oauth2_login=false
# oauth2.token_secret=secret
# Enable SSL for JWT
# If set to true must set paths for the keystore locations
# In case isn't defined default value is false
# oauth2.jwt.use.ssl=false
# URL of Public server JWK set used for validating bearer JWT access tokens
# oauth2.jwk_set.url=http://localhost:8080/jwk.json
# ----------------------------------------------------------- OAuth 2 -----------
# Paths to the SSL keystore files - has to be jks    
#keystore.path=/path/to/api.keystore.jks
#keystore.password = redf1234
#keystore.passphrase = redf1234
#keystore.alias = localhost

Typical endpoint response of URL of Public server JWK set used for validating bearer JWT access tokens :

{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "kid": "rsa1",
      "alg": "RS256",
      "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw"
    }
  ]
}

Step 7: Try a REST call using the header

Using your favorite http client:

GET /obp/v3.0.0/users/current

Body

Leave Empty!

Headers:

Authorization: Bearer ACCESS_TOKEN

Here is it all together:

GET /obp/v3.0.0/users/current HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.47.0 Accept: / Authorization: Bearer "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF6cCI6ImNsaWVudCIsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJleHAiOjE1MTk1MDMxODAsImlhdCI6MTUxOTQ5OTU4MCwianRpIjoiMmFmZjNhNGMtZjY5Zi00ZWM1LWE2MzEtYWUzMGYyYzQ4MjZiIn0.NwlK2EJKutaybB4YyEhuwb231ZNkD-BEwhScadcWWn8PFftjVyjqjD5_BwSiWHHa_QaESNPdZugAnF4I2DxtXmpir_x2fB2ch888AzXw6CgTT482I16m1jpL-2iSlQk1D-ZW6fJ2Qemdi3x2V13Xgt9PBvk5CsUukJ8SSqTPbSNNER9Nq2dlS-qQfg61TzhPkuuXDlmCQ3b8QHgUf6UnCfee1jRaohHQoCvJJJubmUI3dY0Df1ynTodTTZm4J1TV6Wp6ZhsPkQVmdBAUsE5kIFqADaE179lldh86-97bVHGU5a4aTYRRKoTPDltt1NvY5XJrjLCgZH8AEW7mOHz9mw"

CURL example:

curl -v -H 'Authorization: Bearer "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF6cCI6ImNsaWVudCIsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJleHAiOjE1MTk1MDMxODAsImlhdCI6MTUxOTQ5OTU4MCwianRpIjoiMmFmZjNhNGMtZjY5Zi00ZWM1LWE2MzEtYWUzMGYyYzQ4MjZiIn0.NwlK2EJKutaybB4YyEhuwb231ZNkD-BEwhScadcWWn8PFftjVyjqjD5_BwSiWHHa_QaESNPdZugAnF4I2DxtXmpir_x2fB2ch888AzXw6CgTT482I16m1jpL-2iSlQk1D-ZW6fJ2Qemdi3x2V13Xgt9PBvk5CsUukJ8SSqTPbSNNER9Nq2dlS-qQfg61TzhPkuuXDlmCQ3b8QHgUf6UnCfee1jRaohHQoCvJJJubmUI3dY0Df1ynTodTTZm4J1TV6Wp6ZhsPkQVmdBAUsE5kIFqADaE179lldh86-97bVHGU5a4aTYRRKoTPDltt1NvY5XJrjLCgZH8AEW7mOHz9mw" http://localhost:8080/obp/v3.0.0/users/current