JWT tokens are used to secure API calls. There are two typs of tokens we use in API Bridge.
API Bridge internal tokens are used to secure /rpc endpoints. Communication through these endpoints is used oly internally between:
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
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.
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}" ....
Access token from Keycloak is in format of JWT. It must contain the following claim:
This chapter describes possible configuration of Keycloak to achieve claim app_user_id available in the access token.
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.
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.
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.