Securing APIs using JSON Web Token in API Gateway

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

webMethods API Gateway tutorial

Overview of the tutorial

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA. In API Gateway, APIs can be enforced with JWT authentication and the authorization can be done based on the claims present in the JWT.

Required knowledge

The tutorial assumes the reader has,

Why?

JWT's are used extensively now a days in the micro services, because of they are decentralized, portable and stateless. If we don't support JWT, every request should contain some authorization header(like Basic auth) but sending the credentials across for every request is not a good idea. Instead if we have a JWT, user will authenticate using his credentials once and get a JWT. This JWT can be used to invoke the services till its expiry.

Prerequisite steps

  • Install API Gateway 10.3 advanced edition (on-premise installation)

Details

API Gateway can act as both JWT generator and JWT validator.

JWT Generator & Validator

API Gateway can generate the JWT with the configuration you have provided and validate the JWT on its own.

Thirdparty JWT Validator

API Gateway can accept the token from the third party issuer(say like google). For this third-party token you need to configure the third-party certificate or JWKS endpoint in the Gateway for validation.

Configuring JWT

Go to Administration > Security > JWT/OAuth/OpenID and select local and update the fields.

Field

Description

Token issuer

Name of the JWT token issuer used by API Gateway.

Algorithm

The cryptographic algorithm to sign the contents of JWT.
Supported values are: RS256, RS384, and RS512.

Expiry duration

The duration (in minutes) for which the token is valid. For example, the value "60" denotes that the access token will expire in one hour from the time the token was generated.

Audience

Optional. The intended recipient of the token. The application that receives the token must verify that the audience value is correct and reject any tokens intended for a different audience.

Keystore alias

Alias of the keystore containing the private key that is used to sign the contents of JWT.
The Keystore alias box lists all the keystore aliases available in API Gateway. If there are no configured keystore aliases, this box lists the default Integration Server keystore, DEFAULT_IS_KEYSTORE.

Key alias Alias of the private key used to sign the contents of JWT.
The Key alias box is auto-populated and lists all the aliases available in the selected keystore. If there are no configured keystores, this list box is empty.

Requesting a JWT

Once the configuration is done, we can request for a JWT from the gateway in 2 ways.

User authentication with static payload

http://localhost:5555/rest/pub/apigateway/jwt/getJsonWebToken

By default requesting a JWT should be through HTTPS. You can change this in the Administration> General>  Extended settings > pg_JWT_isHTTPS

You can also request a JWT for a particular application. for e.g https://localhost:5556/rest/pub/apigateway/jwt/getJsonWebToken?app_id=9502c862-9e67-4726-bc13-598df42c7fb6 (replace it with you app_id). You can view the content of the token from https://jwt.io/

Payload

  • Sub: Valid IS user who logged who requested for JWT
  • aud: Is audience from the configuration and app_id from request if present
  • iss: Token issuer from the configuration
  • nbf: Time before which the token should not be used
  • exp: Expiry time of token
  • iat: Time at which token is issued
  • app_id: application id if present in the request

Application authentication with dynamic/custom payload

Make POST call to http://localhost:5555/gateway/security/getJsonWebToken and in the body you can add the custom claims.  Before invoking this service make sure that the authorization server is configured for the introspection and the scope mapping is done.

Payload: { "claimsSet": { "name": "srikar", "company": "sag" } }

Identifying the application

JWT is generated on behalf of an application. So an application needs to be uniquely identified to generate a token. Application is identified based on the parameters from the request. Say another APIKey from the header, Username from the basic auth or claims from another jwt in authorization header etc. Define how you want to identify the application and pass those details in the request. Say if you want to identify application using username, then provide the username identifier in the application and while invoking the service send the basic authentication details.

Now if you decode the token, you will also have the claims you have provided in the payload.

Identify & Authorize Application

We can identify an application based on the claims available in the token. Go to Polcies > Identify& Access > Identify & Authorize application > check JWT and select Registered applications/Global applications. Here we first identify the application based on the claimSet provided in the application, authenticate the token and then authorize the request.

In the application configure the claim identifier. We can have multiple claim set and in each claim set we can have multiple claims. Say claim set 1 has 2 claims (sub: Administrator, name: srna) and claim set 2 has another 2 claims (sub: Developer, name lnar). So incoming token should match with either of the claim sets. (sub: Administrator && name: srna) || (sub: Developer && name lnar)

And if you want to validate your JWT using shared key, go to Authentication tab in application and create a strategy.

Outbound Authentication - Transport

If your native service is protected with JWT authentication. You can use the outbound authentication. Go to Routing > Outbound authentication - Transport > Select JWT in auth scheme. We support only Incoming JWT for now, this will send the jwt that is sent by the client directly to native service.

Third party JWT

If you want to authenticate your API with a third party JWT. You can configure this public certificate or provide the JWKS URI and validate if the incoming token is valid or not. To configure this, Go to Administration → Security → JWT/OAuth/OpenID then click Add authorization server. Now as the incoming token is a JWT, we can just configure the local introspection alone. Make sure the issuer name is the same from the token and provide either the JWKS URI or the public certificate of the issuer.

Field

Description

Issuer

Mandatory. Name of the JWT issuer.

Description

A description for the issuer

JWKS URI

Endpoint URI of JSON Web Key Set (JWKS) through which API Gateway fetches the JSON Web Key (JWK) to verify and validate the signature of JWT. API Gateway fetches a JWK, whenever the API Gateway instance is started or the JWKS URI field is updated.

If you do not specify a value for this field, you must specify values for the Truststore alias and Certificate alias fields.

Truststore alias

Alias of the truststore that contains the certificates of the signing authorities associated with the issuer. The truststore alias can be used to verify the signature of a JWT when the JSON Web Key endpoint is not specified. The Truststore alias field contains a list of the public certificates that are trusted by API Gateway.

Certificate alias

Alias of the certificate associated with the truststore alias. The Certificate alias field contains a list of the available certificate aliases in the selected truststore.

Audience check

When an audience is present in the token, API Gateway validates the audience to verify that the token is intended to invoke this particular resource. Either one of the below audience check should match then only API Gateway allows accessing the resource.

  • Token is intended for a particular application - Audience can be configured in the JWT strategy(available from 10.3 Fix 6)
  • Token is intended for the API Gateway - matches with the audience from the API Gateway JWT configuration
  • Token is intended for the API - Audience of token should match with the request URI
  • Token is intended for the Application - Audience of token should match with the identified application id

Using JWT in Microgateway

JWT 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 JWT in 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. The public key of the JWT configuration in API Gateway is exposed to Microgateway through this URI. Microgateway will use this public key to locally introspect the JWT Token.

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: "********************************"
...

The other properties in this setting are not relevant for JWT and is relevant for introspection of oauth tokens sent to Microgateway. Please refer Securing APIs using OAuth 2 in API Gateway for more details.

What changed from 10.2

  • JWT, OAuth, OpenID configuration are merged into a single place.
  • Inbound authentication transport is merged into Identify & Authorize user
  • Support of custom claims in generation of JWT
  • Support of JWT validation using HMAC algorithm

Limitations

  • Gateway acting as a JWT issuer will only provide tokens with RS algorithm

References

Troubleshooting

# Issue Solution
1

if you get unable to uniquely identify application in getJWT Post call

Try adding more identifiers of the application in the request.
2

JWT configuration empty

 

Go to local authorization server and provide the JWT configuration.

Learn more