Bearer tokens in API

JWT tokens are used to secure API calls. There are two typs of tokens we use in API Bridge.

API Bridge internal JWT token (legacy)

API Bridge internal tokens are used to secure /rpc endpoints. Communication through these endpoints is used oly internally between:

  • ERP UI and API Bridge
  • Iptor CRM and API Bridge
  • Iptor CRM Notification engine and API Bridge
  • P27 done using NiFi and API Bridge
  • Aperio Client (mobile apps) and API Bridge
  • New sales order entry and API Bridge

To obtain token from API Bridge, client application muust first call POST /rpc/login and provide as payload: user, password, DC1 company code. User and password are for IBM i. As response, API Bridge issues token and refreshToken. These two tokens must be saved in client application storage. Then every future API call must be accompanied with token in the authorization HTTP header.

Example of loging in and obtaining API Bridge internal tokens

curl -d '{"user":"myIBMuser":"password":"myIBMpassword", "company":"CD1-company"}' -X POST {api bridge address}/rpc/login

Example of sending Bearer JWT token in the authorization header

curl --header "Authorization: Bearer {token}" -d '{"control":{"method":"items.get"}}' -X POST {api bridge address}/rpc/service

Access token and refresh token have their own expiration times. When the access token is about to expire application needs to refresh it by sending request to /rpc/refreshToken endpoint. This time the request must be accompanied with refreshToken.

Example of sending a request to refresh access token.

curl --header "Authorization: Bearer {refreshToken}" -X POST {api bridge address}/rpc/refreshToken

When application wants to end work it is recomended to send logout request to release IBMi resources Example of logout (release IBM i resources).

curl --header "Authorization: Bearer {token}" -X POST {api bridge address}/rpc/logout

or

curl --header "Authorization: Bearer {token}" {api bridge address}/rpc/logout

Keycloak access token

The general idea is to migrate from Iptor internal tokens to access tokens from authentication providers using Oauth 2.0 standard. Currently Iptor uses Keycloak as central authentication solution.

API call

The API Bridge checks every request against Keycloak and verify if access token is valid. To be possible to call any API you need to include access token in authorization header of HTTP request. This header should contain access token obtained from Keycloak. The token should be prefixed with word “Bearer”.

curl --header "Authorization: Bearer {access token}" ....

Keycloak configuration

Access token from Keycloak is in format of JWT. It must contain the following claim:

  • app_user_id - this is the user profile on IBM i on behalf of which the session on IBMi will be created

Keycloak access token configuraton

This chapter describes possible configuration of Keycloak to achieve claim app_user_id available in the access token.

User profile

At user profile level in Keycloak, define a new attribute: “app_user_id”. Set the value of this attribute to IBM i user profile.

NOTE: IBM i user profile must have possibility to use Aperio backend. Usually, it means it should have APIPRF supplemental group profile added. Contact your system administrator to make sure if your user is able to run API.

Client

Next element is to set up your client in Keycloak. Depend on Keycloak version the configuration may differ. The main element of this configuration is to set up that app_user_id value should be added to token mappers. For Keycloak ver 19 or higher you need to go to Client then go to the Client scopes. On Client scopes level click on dedicated scope. You will be reddirected to Mappers. Then add a mapper “app_user_id” as a user attribute.

Example of Mapper confg in Keycloak

Authentication for API call using Postman

There are two ways to authenticate with Keycloak from Postman. Before you start configuring Postman you need to know which URKs are supported by Keycloak. Go to Realm settings and click OpenID endpoint configuration. Usually the address of this configuration is under the followig URL:

{keycloak server and port}/auth/realms/{your realm}/.well-known/openid-configuration or {keycloak server and port}/realms/{your realm}/.well-known/openid-configuration

Example of JSON representing OpenID configuration for realm “Iptorcom”

{
    "issuer":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom",
    "authorization_endpoint":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/auth",
    "token_endpoint":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/token",
    "introspection_endpoint":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/token/introspect",
    "userinfo_endpoint":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/userinfo",
    "end_session_endpoint":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/logout",
    "frontchannel_logout_session_supported":true,
    "frontchannel_logout_supported":true,
    "jwks_uri":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/certs",
    "check_session_iframe":"https://dkdcvs134.iptor.com:18447/realms/Iptorcom/protocol/openid-connect/login-status-iframe.html",
    "grant_types_supported":[
        "authorization_code",
        "implicit",
        "refresh_token",
        "password",
        "client_credentials",
        "urn:ietf:params:oauth:grant-type:device_code",
        "urn:openid:params:grant-type:ciba"
    ],
...
}

For more information see Postman article.