KB Article #188562

Change in JWT Verify Filter Output Type in May2024 Release

Problem

Starting with the May 2024 release of API Gateway, there has been a significant change in the output type of the jwt.body attribute in the JWT Verify filter when the attribute format is set to JSON.


In versions prior to Feb 2024, the jwt.body was generated as an object of type:

  • com.nimbusds.jose.shaded.json.JSONObject

However, with the May 2024 release, the same jwt.body is now being generated as:

  • com.nimbusds.jose.shaded.gson.internal.LinkedTreeMap

This change in output type has caused failures in certain scripting filters that rely on the previous JSONObject type.

Resolution

This behavior change is due to an upgrade of the nimbus-jose-jwt library to version 9.37.3, which was introduced for security reasons. As part of this upgrade, several interfaces of the library were modified. Specifically:

  • The com.nimbusds.jose.Payload class has undergone the following change:
    • Previous: public JSONObject toJSONObject()
    • Now: public Map<String, Object> toJSONObject()
  • The com.nimbusds.jose.JWSHeader class has also changed:
    • Previous: public JSONObject toJSONObject()
    • Now: public Map<String, Object> toJSONObject()

These modifications result in the jwt.body being generated as a LinkedTreeMap instead of a JSONObject.

Currently, there is an ongoing assessment (tracked in JIRA RDAPI-31810) to evaluate the extent of this change and identify an appropriate long-term solution.


In the meantime, the following workaround can be applied to convert the jwt.body output from a LinkedTreeMap back to a JSONObject:


  1. Import into PolicyStudio the library from ./system/lib/modules/nimbus-jose-jwt-9.37.3.jar
  2. Use a Scripting filter to convert the generated output to a JSONObject with the following Groovy script:
import com.nimbusds.jose.shaded.gson.Gson;
import com.nimbusds.jose.shaded.gson.JsonObject;

def invoke(msg)
{
Gson gson = new Gson();
        
JsonObject jsonObject = gson.toJsonTree(msg.get("jwt.body")).getAsJsonObject();
msg.put("jwt.body", jsonObject );
return true;
}