Securing APIs using OAuth 2 in API Gateway

Author: Naramsetty, Srikar <Srikar.Naramsetty@softwareag.com>
Supported Versions: 10.3 and above

For securing APIs using OAuth2 in API Gateway for versions 10.2 and below please refer https://tech.forums.softwareag.com/t/securing-apis-using-oauth2-in-api-gateway

webMethods API Gateway tutorial

Introduction

OAuth 2 is an authorization framework that enables applications to obtain limited access to user accounts. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account. In this tutorial we will go through the following steps in detail to use OAuth2 in API Gateway.

  • Configuring local authorization server
  • Importing travel services into API Gateway and creating the scopes for the resources
  • Enforcing OAuth2:
  • Linking authorization server scopes to the API Scopes
  • Creating BookYourTicket application in API Gateway
  • Getting bearer token
  • Invoking the API
  • Using properties of access token
  • Refreshing access token
  • Enabling OAuth 2 authorization through HTTP
  • Removing expired tokens
  • Customizing the default approval page

Required knowledge

The tutorial assumes that the reader has:

  • a basic understanding of API Gateway and its policy enforcement
  • a basic knowledge on OAuth 2 authentication framework

Why?

Lets assume you have a service and you want to protect it with OAuth2. You can use the API Gateway OAuth2 authorization server to generate the access tokens for the client applications.

Prerequisite steps

  • Install API Gateway 10.3 advanced edition
  • Install postman REST client of version >= v6.0.10

Details

Below is the OAuth2 flow using API Gateway.

Grant types are the ways to get an access token from the authorization server. API Gateway supports all the 4 grant types:

  1. Authorization code along with refresh token
  2. Implicit
  3. Resource owner password
  4. Client credentials

Lets go through the following steps in detail.

Step 1: Creating API

Import the archive Time%20travels.zip, this archive contains an API "Time travels" which have the below resources. This API is protected with OAuth2, so any request to this API without a valid access token will be rejected with 401 status code.

API Scope Resource Explanation

 

ViewTickets

Which retrieves all the bookings done

Retrieves a particular booking
BookTickets

Resource to book the tickets
CancelTickets

Resource to cancel the existing booking.

For these we shall define 3 scopes in the oauth2 authorization server (book, view and cancel) and we map the authorization scope to the API Scope. This way we can restrict the usage of the access token with a scope to particular resources.

Authorization server scope

API scope
book BookTickets
cancel CancelTickets
view ViewTickets

Once this is done, a client needs to be created in the authorization server for a client application. Then client application will request the access tokens from the authorization server and invokes the protected APIs and gets the response.

Now lets see how all this is done in API Gateway.

Step 2: Configuring local authorization server

Go to administration ->security→ JWT/OAuth/OpenID

In internal authorization servers, Local authorization server is gateway acting as the authorization server. Click on local. You can see the OAuth configuration, issued OAuth tokens and OAuth scopes.

OAuth configuration: You can change the default authorization code expiry interval and access token expiry interval.

OAuth tokens: Tokens that are issued by the local authorization server, Administrator can revoke the token directly from here.

OAuth scopes: Scopes are the ways to limit the access to the protected resources. Scopes are generally the business uses(say readonly, write, inventory). You can define your own scopes here. I will provide 3 business scopes, view, book and cancel.

Step 3: Importing travel services into API Gateway and creating scopes for resources

API Scopes

Step 4: Enforcing OAuth 2

Edit Time travels API in API Gateway. Click Edit. Click Identity and Access management. Click Identify and authenticate icon. Tick OAuth2 Token. This procedure will enforce OAuth authorization for this service.

Step 5: Linking authorization server scopes to the API Scopes

Now the authorization server has scopes like view, cancel, book. But what does they mean in Gateway? How can they limit the access to the resources?

  1. View scope can only access the GET resources of Booking
  2. Cancel scope can access only the DELETE resource 
  3. Book scope can only access the resource used for  booking a ticket

To provide the meaning to the authorization server scopes. Go to OAuth/OpenID scopes under main menu. Click "Map scope".

Here map the authorization scopes to the API Scopes.

Step 6: Creating BookYourTicket application in API Gateway

Now we need to create the application in API Gateway, register the API with the application and create a strategy for OAuth2. Strategy are the ways to authenticate the incoming request.  Inside the strategy you can decide if you want to create a new client in the authorization server or use the existing client in the authorization server. Depending upon your type of application, you can decide what kind of client you want to create. Token lifetime is the amount of time the given access token will be active. If you doesn't want your token to expire then you can provide the value as -1. Token refresh limit is the number of times you can use the refresh token to get a new access token. Default value is 0. If the refresh limit is zero then the refresh token will not be generated.

As I have clicked generate credentials in the strategy a new client was created in auth server. And the client details are available in the view mode of application.

Step 7: Getting bearer token

Getting the access token from authorization server is generally responsibility of the application. To understand the flow, I will explain this using postman. We will use the postman app for google chrome in this tutorial to get the bearer token. The following details are needed to get the bearer token.

  • Auth URL: https://<client_id>:<client_secret>@<IS_HOST>:<IS_PORT>/invoke/pub.apigateway.oauth2/authorize
  • Access Token URL: https://<client_id>:<client_secret>@<IS_HOST>:<IS_PORT>/invoke/pub.apigateway.oauth2/getAccessToken
  • Client ID: Could be found in API Gateway application details page (See above picture)
  • Client Secret: Could be found in API Gateway application details page

Postman UI for entering OAuth 2.0 Authorization details

Once the Request Token is clicked, you will be getting this popup with the services to which you want to give access to. 

Make sure what are the access you want to approve. Here I want to provide access only to view my tickets so selected only that and approved. Once it is approved, Postman will receive the bearer token with all the given access, and this token can now be used by the external application to invoke the Time travels services.

Getting access token without Postman

Invoke the authorization URL (http://localhost:5555/invoke/pub.apigateway.oauth2/authorize?client_id=f03f3e72-7dda-4006-b678-2d2e7469faab&redirect_uri=http://bookyourticket.com/redirect&response_type=code&state=121) replace CLIENT_ID and REDIRECT_URI with your values. Approve the access  Grab the authorization from the redirect URI.

Then invoke access token url using the postman', Change the values accordingly. If the client is a confidential client, then include the client_id and client_secret in the basic authorization. 

Extract the access token and use it to invoke the API.

Step 8: Invoking the API

With the token which i got I tried to invoke the API to get all the bookings, and I get the proper response.

But when I try to invoke the API to book the tickets, I get the error message. Token is invalid or expired. This is because I have provide access to only the view scope, which links to the view tickets scope of API (Refer to step 3), So with this token I wont be able to access the other resources.  This process with the same for the external application also. Now the BookYourTicket application can only view your tickets, but cannot book tickets on behalf of you.

Step 9: Using properties of access token

You can use the properties of the access token  like clientId, owner for further processing using the request transformation policy. Look at Request and Response Transformation policies in API Gateway.

${request.authorization.clientId}

 

 

 

request

 

 

 

 

 

 

 

 

authorization

clientId

issuer

userName

authHeader

incomingToken

Step 10: Refreshing access token

While getting the bearer token as in the previous step, we can optionally get a refresh token, that could be used to get a new access(bearer) token without having  user  to grant the request again. The refresh token will be generated only if the refresh limit while generating the client is more than 0. Once the token refresh limit is set to non-zero. A refresh token will be generated as part of the access token that is generated. As shown below.

In order to refresh the access token, the request should be formed as shown below. The following endpoint should be used https://<IS_HOST>:<IS_PORT>/invoke/pub.oauth/refreshAccessToken

Now you can use the new access token and use it to invoke the APIs

Step 11: Enabling OAuth 2 authorization through HTTP

The entire process could be executed using http instead of https. This needs the following configurations. Enable API Gateway to accept request through http. Go to Administration→ General→ Extended setting → Show and hide keys → select pg_oauth2_isHTTPS and change the value to false . If you want to use the refreshtoken to be used via HTTP, you can set watt.server.oauth.requireHTTPS to false.

Step 12: Removing expired tokens

Scheduling the removal of the expired tokens is customers job. Some customer wants to clean it daily and some might want to do it weekly/monthly. So API Gateway expose a service which when called will clean all the expired tokens. The service isURL is http://localhost:5555/invoke/pub.oauth/removeExpiredAccessTokens

Step 13: Customizing the default approval page

Below is the default approval page. But it can be customized to the your need. For that go to the <<installation-dir>>\IntegrationServer\instances\default\packages\WmAPIGateway\templates and edit the OAuth_Approval.html and customize the CSS and the headers to your need.

URL's

Type
URL
Access token

https://<IS_HOST>:<IS_PORT>/invoke/pub.apigateway.oauth2/getAccessToken

Authorize

https://<IS_HOST>:<IS_PORT>/invoke/pub.apigateway.oauth2/authorize

Refresh token https://<IS_HOST>:<IS_PORT>/invoke/pub.oauth/refreshAccessToken

Using OAuth in Microgateway

OAuth policy can be configured in Microgateway from version 10.4. The administration settings for JWT can be configured in Microgateway either by copying settings from API Gateway server or by provisioning the values in YAML file during startup.

Authorization servers

Download Settings from API Gateway

Configure api_gateway → download_settings property as "true" in the YAML file to download the settings of API Gateway and use them in Microgateway. This helps to download the settings under Administration → JWT/Oauth/OpenID into Microgateway.

downloadSettings.yml

ports:
  http: 4485
  https: 7749
api_gateway:
 url: "http://localhost:5555"
 user: "Administrator"
 password: "{encoded}bWFuYWdl"
 dir: "C:/Installations"
 download_settings: true
...

Configure using YAML file

Configure the security_settings as provided in this file  microgateway_jwt_oauth_openid.yml.

Local Introspection of OAuth tokens in Microgateway

OAuth tokens cannot be locally introspected directly by Microgateway. The introspection can be delegated to to API Gateway using the below properties.

introspectionEndpoint

Introspection endpoint of API Gateway (http://<HOST>:<PORT>/invoke/pub.oauth/introspectToken)

clientId

Client Id of client in API Gateway. This client is used for authenticating the remote introspection request originated from Microgateway. 

clientSecret

Client secret of client in API Gateway. This client is used for authenticating the remote introspection request originated from Microgateway. 

Download Settings from API Gateway

This is same as the above section (Authorization servers). This helps to download the JWKS URI setting under Administration → Microgateway into Microgateway.

Configure using YAML file

Configure the security_settings → auth_servers → localIntrospectionConfig → jwksuri as shown below.

--- !<authServerAlias>
id: "local"
name: "local"
description: "API Gateway as an Authorization server."
type: "authServerAlias"
owner: "Administrator"
localIntrospectionConfig:
  issuer: "test-gateway-issuer"
  trustStoreAlias: null
  certificateAlias: null
  jwksuri: <CONFIGURE JWKS URI HERE>
  description: null
remoteIntrospectionConfig:
      introspectionEndpoint: "http://localhost:7777/invoke/pub.oauth/introspectToken"
      clientId: "6775021a-2fa8-4166-95c9-588774f55f49"
      clientSecret: "********************************"
...

JWKS URI property in this section is not relevant for OAuth and is relevant only for introspection of JWT tokens by Microgateway. For more details please refer Securing APIs using JSON Web Token in API Gateway.

What changed in 10.3?

  • API Gateway won't automatically create the scope mapping when an API/API Scope is associated to an application. Administrator needs to provide the business scope in Local authorization server(say read-only, write) and then the API provider should provide the mapping for the scope in authorization server to the API/API Scopes
  • OAuth configuration and token management can also be done in API Gateway
  • OAuth credentials wont be created by default when an application is created in API Gateway. Instead a strategy needs to be created in application for the OAuth credentials
  • Prior to 10.3 API Gateway was creating only Confidential clients, now both public and confidential clients can be created

Troubleshooting

Issue Solution
If you get an access exception while trying to get an access token using postman
Go to the step 6 and try to invoke the URLs directly.
If you are calling getAccessToken and your OAuth client is a confidential client, then you need to provide the client_id and client_secret in the basic authorization header.

References

Downloadable artifacts

Learn more

Time travels.zip (19.5 KB)

Impossible to make it work. Asking for credentials on browser level even for public oauth2 clients. Postman doesn’t let you enter credentials and soapUI can not even load the authentication page provided by API GW.

At browser level it’s possible to provide credentials but still returns http 403.

Could anyone make it work after migrating to 10.5?