In the first part of the series, we provided a
brief introduction of oauth and the various security policies
available within ICS. We also had a closer look at OAuth Custom
Two Legged Flow. In this post, we will look at OAuth Custom
Three Legged Flow. The final part in this series provides the sample
custom OAuth Security configuration for some of the popular
services.
Before we delve into custom 3-legged security policy, it is
important to understand the steps performed as part of
OAuth Authorization code credentials flow:
Figure 1 OAuth Authorization Code Flow
Step 1: User specifies the authorization request URI. The
user is redirected via the user-agent (browser) to the
authorization URI.
Step 2: Resource owner logs in to authenticate and provides
consent to the client application to access its resources.
Step 3: The authorization server sends a callback request to
the client application and sends the authorization code.
Step 4: The client application extracts the authorization
code from the request and uses it to send another request to the
authorization server to get an access token.
Step 5: The authorization server responds to the access
token request by sending an access token to the client
application.
Step 6: The client application uses the access token to make
requests for protected resources.
This flow is fairly well defined in the OAuth specification but how
each step in the flow should be performed is left to the
authorization server implementing the OAuth flow.
Few variations that we have observed are as follows:
Sno.
Variation
1.
OAuth provider expects that some query params should be passed
along when the user is
redirected to the authorization URI.
2.
The provider calls authorization code something else.
3.
The call for the access token should include the auth code but
some provider may
expect it as a header or a query param or maybe part of the
data.
4.
The access token response may also wary. Some providers may
return a refresh token, call
it say extended_token or something else. We have seen providers
return expiry
whereas some providers return a jwt token where expiry is embedded
as a claim
within the token.
5.
Providers may also declare a custom token type.
6.
The call to refresh the access token may also vary from provider
to provider.
7.
The call to access resources using the access token may also vary.
Providers
may expect it to be a header or a query param. Some providers ask
the token
to be passed as an Authorization header, few providers expect a
custom header
etc…
Figure 2 Variations in OAuth
To summarize, we can say that, while we have reasonable
information about the OAUTH flow but each step in the flow can
vary.
Generic REST adapter comes with a security policy called the
OAuth Authorization Code Credentials flow. This policy
provides a specific implementation of the OAuth as illustrated in
the OAuth specification. For all other cases, OAuth Custom Three
Legged Flow can be used to address these customizations.
Step 1: Configure the Authorization Request
Figure 3 Specify the authorization request
The first step would be to specify the authorization uri where
the resource owner will authenticate and provide consent. Typically
the clientID and scope are passed as query parameters along with
the redirect_uri where the authorization server must send a
callback along with the auth code.
ICS has a fixed endpoint to receive this callback so users can
specify the URI directly or pass a reference
${refresh_token} that will be automatically
resolved by the platform.
Example:
https://<authURI>?response_type=code&client_id=[YOUR_CLIENT_ID]&redirect_uri=${redirect_uri}&scope=<app_scope>
Step 2: Configure the Access Token Request
Figure 4 Specify the access token request
When the resource owner provides consent, the authorization
server sends a callback to the client application along with the
authorization code. The next step is for the client
application to send a request for the access token using this
authorization code.
* If the authorization server returns the authorization code in
a property named as anything but code, then the users need to map
the property name with $auth_code.
The access token request is used to make a call for the access
token. It is supposed to send the authorization code which is not
resolved till the flow is executed. Thus authorization code is
passed by reference as ${auth_code} in the
request.
The rules for create the access token request remain unchanged from
custom two legged flow.
Access Token Request is formed using a URI
syntax of the http request used to
fetch the access token. The URI syntax resembles cURL but it is
much basic and only supports the following
options.
SNO.
Option
Value
description
Required
1.
-X
GET|PUT|POST
http verb
in the access token request
Yes
2.
-H
-H “key:
value”
Each
header key value pair should be added as described. There can be
multiple
headers.
No
3.
-d
-d
‘data-as-string’
String
data enclosed within single quotes. Any quotes within the data
string should
be escaped.
No
4.
Uri
Uri within
quotes
Yes
Figure 5 URI Syntax Options
Please note: other curl options are not
supported.
The easiest way to build this request is by using a free tool
like POSTMAN or Restlet client to build and validate the http
request to obtain an access token and then use the Generate Code
Snippet/Code option to get a cURL syntax. Remove the curl from
the head to get the URI syntax.
Exmaple URI Syntax:
-X POST -H "Content-Type: application/x-www-form-urlencoded" -d
'false'
https://<access_token_URI>?code=${auth_code}&client_id=[YOUR_CLIENT_ID]&client_secret=[YOUR_CLIENT_SECRET]&redirect_uri=${redirect_uri}&grant_type=authorization_code'
Step 3: Optionally configure the refresh token request
Figure 6 Specify the refresh token URI syntax
Similar to access token request, specify the refresh token
request in URI syntax, if the authorization server supports
refresh.
Step 4: Define the fetch rules for intermediate tokens
Figure 7 Variables along
with property mapping
By default, the $variables are mapped to property names
containing relevant tokens as follows:
Variable
name
Default
mapping to a property with name
Example
property name
1.
$auth_code
code
code
2.
$access_token
access.[tT]oken
access_token
3.
$refresh_token
refresh.[tT]oken
refresh_token
4.
$token_type
token.?[tT]ype
token_type
5.
$expiry
expires_in
expires_in
Figure 8 Default variables and their property
mappings
If the access token response from the authorization server is
conforming to the table above and as illustrated below, then the
fetch rules are not required.
However, if the access token response is not standard, then users
need to define rules to fetch tokens from the access token
response.
Step 5: Define the access token usage (Important)
Access token usage describes how the access token should be
passed for accessing a resource. Please enter this information
carefully since this usage will govern how ICS will pass the
negotiated access token to the endpoint.
Figure 9 Access Token Usage
In this second part of the series, we saw some of the basic
constructs of OAUTH Custom Three Legged Policy. In the
next part we will recap the syntax for each field and the final part will list down
the
sample configuration for some of the popular OAUTH Protected
services.
Do re-visit the first part of the series, that provides a brief
introduction of oauth and the more flexible custom security
policies available within ICS, which are particularly useful in
integrating with OAuth protected RESTful services. This also
provides an overview of OAuth Custom Two Legged security policy for
obtaining an access token from an authorization server.