Validating JWTs generated by external OAuth providers — WSO2 APIM

Nadee Poornima
5 min readMay 18, 2024

--

Hello, my dears … ❤❤

Ref: https://www.pinterest.com/pin/828943875146773458/

After a long time, I hope everyone is doing great. Today, I am writing a short story about validating JWTs (JSON Web Tokens) on WSO2 APIM.

From APIM 3.0.0 onwards, WSO2 APIM used JWT as their default access token, and the Gateway itself could be validated. Previous versions used opaque tokens as the default access token, which was generated and validated via the key manager node. Therefore, the JWT uses only a key manager for generation, and validation happens with the GW. Hence, it improves the performance of APIM by reducing the multiple KM calls when invoking APIs.

JSON Web Token (JWT) is an open standard of transmitting information securely between two parties. As the tokens are digitally signed, the information is secured. The authentication and authorization process uses JWT access tokens. It is ideal to use JWT access tokens as API credentials because JWT access tokens can carry claims (data) that are used to authenticate and authorize requests.

WSO2 APIM allows only signed JWT access tokens, and the expected token format is as follows.

base64(header).base64(payload).base64(signature)

The public certificate of the private key that is used to sign the tokens should be added to the trust store under the "gateway_certificate_alias" alias.

Let’s see how to validate these JWT access tokens using the APIM GW itself when the JWT has been generated via an external OAuth provider.

Once the API request with the JWT access token is reached by the APIM GW component, first validate the signature of the JWT token, then validate the scopes. Finally, the user is allowed to access the requested API resource if all validation is passed successfully.

Signature Validation

JWT tokens have been signed with the private key of the OAuth provider. Therefore, GW required the public key to validate the particular signed JWT. The public key can be retrieved from the JWKS endpoint or “client-truststore.jks” of the GW. Let’s see how this signature verification is happening on GW.

  1. Extract the JWT Header: Decode the JWT and extract the header part. This part of the JWT is typically Base64URL encoded. The header contains metadata about the token, including the `alg` (algorithm) and `kid` (key ID) fields.

2. Retrieve the `kid` Value: From the decoded header, obtain the `kid` value. The `kid` is a hint indicating which key should be used to verify the signature.

  • If a kid is not present in JWT, it will validate with the public certificate under the “gateway_certificate_alias” alias from the “client-trust store.jks”.
  • Note: By default, WSO2 APIM signs the JWT token with the private key of the primary certificate in the primary keystore (wso2carbon.jks)
  • We should import the public certificate of the external OAuth provider into the “client-truststore.jks” located at <API-M_HOME>/repository/resources/security/ with the kid value of the certificate as the alias.

3. Fetch the Key Using `kid`: Use the `kid` value to fetch the corresponding public key or secret from the key store. This key store could be a local file, a database, or a remote endpoint (e.g., a JWKS endpoint in case of public keys from an authorization server).

  • When JWT is generated by the external OAuth provider, GW will call the JWKS endpoint to retrieve the JWK key for the relevant KID value.
  • JWKS(Json Web Key Sets) Endpoint: The JSON Web Key Set (JWKS) is a set of keys containing the public keys used to verify any JSON Web Token (JWT) issued by the Authorization Server and signed using the RS256 or HS256 signing algorithm.
  • The JWKS endpoint is defined on the “deployment.toml” file under the [[apim.jwt.issuer]] tag.
[[apim.jwt.issuer]]
name = "https://localhost:9443/oauth2/token"
jwks.url = "https://localhost:9443/oauth2/jwks"
  • Once the Public keys are retrieved from the JWKS endpoint, and verify whether the JWK key exists for the relevant KID.
  • If the public key doesn’t exist for the relevant KID value, GW will throw a Token Validation error for the client.
  • In any case, if you haven’t defined the JWKS URL, then the GW retrieve the public certificate from the “client-truststore.jks” and considers the alias as the kid value. Therefore, you should make sure to import the public key of the OAuth provider.

4. Verify the JWT Signature: Using the appropriate public key retrieved in the previous step, verify the signature of the JWT. The exact verification process depends on the algorithm specified in the `alg` field of the JWT header (e.g., RS256, HS256).

  • Note: The JWTs generated by external OAuth providers can be validated only if the tokens are signed by an asymmetric algorithm such as RS256. Symmetric algorithms such as HS256 are NOT supported in the validation flow.

5. Validate Claims: If the signature is valid, proceed to validate the claims in the JWT payload, such as `exp` (expiration time), `iat` (issued at time), `iss` (issuer), and `aud` (audience) to verify the validity of the token.

If signature validation is ok, then move to the Scope validation.

Scope validation

By default, the WSO2 API Manager validates the scopes coming in the scope claim of the JWT. If the JWT contains the scopes in a different claim, users can map that claim into the scope claim as per JWT claim transformation.

  • The “default” is the default value for the ‘scope’ claim of the JWT.

Summary

Reference: https://apim.docs.wso2.com/en/4.2.0/design/api-security/oauth2/access-token-types/jwt-tokens/#signature-validation

Certificate Renew Process and How It Affects the JWT Validation

If you use the default server private key to sign JWT tokens, then if you renew it without using the same private-public key pair (you have generated a new certificate and imported it to the server), old generated valid JWT tokens will be invalid regardless its validity period. Becuase old private and public keys are unavailable to verify the signature with the given alias.

Therefore, you should renew your certificates while keeping the same private-public key pair. Then, The internally encrypted data will not be affected. Follow this blog post, which explains how to renew the CA and Self-signed certificates while keeping the old private-public key pair.

Reference

So, That’s it … I hope this is useful when studying the JWT token validation process. Don’t forget to clap and comment here.

Bye bye ….

Ref: https://mondemerda.blogspot.com/2010/02/tom-and-jerry-70th-anniversary.html

--

--

Nadee Poornima
Nadee Poornima

Written by Nadee Poornima

Senior Software Engineer at WSO2

Responses (1)