/images/resources/howtos/gateway/ibm-api-connect/curity-article-ibm-connect.png

Integrating with IBM API Connect using the Phantom Token Pattern

On this page

The IBM API Connect Gateway is a powerful API Gateway that is used to protect APIs and Microservices. It is possible to extend the capabilities of the gateway using many of the provided policies. Using a couple of these policies in conjunction with a Lambda Authorizer function can implement the Phantom Token Pattern in a secure way.

This article describes how to configure IBM API Connect to use a Lambda Authorizer that is exposed using a Function URL. The Lambda Authorizer introspects an opaque access token and returns a JWT that is used to access the upstream API. The API Gateway adds the JWT to the Authorization header and forwards the request to the upstream API.

The details of the OAuth Introspection and Phantom Tokens is a useful read before diving fully into how to set up this integration.

Lambda Authorizer for Other API Gateways

Although this article describes how to leverage a Lambda Authorizer with the IBM API Connect Gateway, it is possible to use the same approach and the same Lambda Authorizer with other API Gateways that supports the use of Lambda Authorizers.

Prerequisites

  • An installation of the Curity Identity Server
  • An IBM API Connect Gateway
  • Basic understanding of Lambda functions

If you do not have an installation of the Curity Identity Server, you can follow the Install using Docker tutorial and then follow the First Configuration tutorial to make OAuth endpoints available.

Configure the Curity Identity Server

The Curity Identity Server needs to be set up to handle introspection. This is the case by default but review the configuration of the system in use before continuing and also make sure you have a Client configured for introspection.

This article assumes that the Curity Identity Server is set up to handle the application/jwt approach of introspection as outlined in the OAuth Introspection and Phantom Tokens article.

Build, Deploy and Configure the Lambda Authorizer Function

The code for the Phantom Token Lambda Authorizer function is available in the GitHub repository. Full details on building, deploying and configuring the Lambda Authorizer function itself is outlined in the README.

Configure the IBM API Connect Gateway

The steps below outlines the flow that is implemented in the IBM API Connect Gateway. These steps assume that you already have an API configured that the gateway is proxying.

  1. Extract the opaque access token from the Authorization header of the incoming request and store it in a variable
  2. Build the payload for the Lambda Authorizer function and add the access token
  3. Call the Lambda Authorizer function and pass on the payload
  4. Parse the response from the Lambda Authorizer function and store the JWT in a variable
  5. Inject the JWT into the Authorization header of the request to the upstream API

An example policy snippet that implements the above steps is available in Appendix A at the end of this article. The example is a YAML configuration that can be used in the IBM API Connect Gateway.

Test Using OAuth Tools

  1. In OAuth Tools, create a flow to obtain an Access Token.
  2. Create a Call External API flow. Enter the URL of the IBM API Connect Gateway exposed API. Configure the method according to what’s possible with the API. Select the token retrieved in the previous step from the drop-down list and click Send.

Access Token Expiry

When you use the phantom token plugin, access token expiry responses can originate either from upstream APIs or the plugin itself. In either case, clients receive an HTTP 401 response and can deal with that condition resiliently. Typically, the client runs a token refresh operation and retries the API request with a new access token. To ensure the correct expiry response, the plugin returns statusCode: 401 and the gateway configuration captures that and returns the same status code.

Resources

Useful resources that cover the topics of this article.

Appendix A - IBM API Connect Example Configuration

yml
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
assembly:
execute:
- set-variable:
version: 2.0.0
title: Extract Access Token
actions:
- set: access_token
value: >-
substring-after(context.get('request.headers.authorization'),'Bearer ')
type: any
- set-variable:
version: 2.0.0
title: Build Lambda Request Payload
actions:
- set: lambda_payload
value: >-
json-stringify({type: 'TOKEN',authorizationToken: concat('Bearer', $(access_token))})
type: any
- set-variable:
version: 2.0.0
title: Set Payload for Lambda (via message.body)
actions:
- set: message.body
value: $(lambda_payload)
type: any
- invoke:
version: 2.3.0
title: Call Lambda (Phantom Token)
backend-type: json
header-control:
type: blocklist
values: []
parameter-control:
type: allowlist
values: []
http-version: HTTP/1.1
timeout: 60
verb: POST
chunked-uploads: true
persistent-connection: true
cache-response: no-cache
cache-ttl: 900
websocket-upgrade: false
target-url: [your-lambda-function-url]
headers:
- name: Content-Type
value: application/json
output: lambdaResponse
- parse:
version: 2.2.0
title: Parse Lambda Response
input: lambdaResponse
parse-mode: json
output: lambdaJson
use-content-type: true
parse-settings-reference:
parse-settings:
document_type: json
- switch:
version: 2.1.0
title: switch
case:
- condition: lambdaResponse.status.code = 401
execute:
- throw:
version: 2.1.0
title: throw
error-status-code: '401'
name: Introspection error
error-status-reason: Unauthorized
message: Invalid token
- set-variable:
version: 2.0.0
title: Inject JWT in upstream request
actions:
- set: message.headers.Authorization
value: Bearer $(lambdaJson.body.access_token)
type: string
- invoke:
title: invoke
version: 2.0.0
verb: keep
target-url: $(target-url)
follow-redirects: false
timeout: 60
parameter-control:
type: allowlist
values: []
header-control:
type: blocklist
values: []
inject-proxy-headers: true
chunked-uploads: true
persistent-connection: true
Newsletter

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Newsletter

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial

Was this helpful?