KB Article #180851

How to Base64Url decode a JWT

Problem

  • Scripting filter example "Base64 Decode" does not handle Base64Url format (RFC 4648 Sec 5, link).
  • com.vordel.common.base64.Decoder only decodes Base64; not Base64URL as used by JWT.
  • How to Base64Url decode a JWT token via scripting, without using JWT Verify filter.
  • JWT Verify filter only provides a decoded jwt.body if verify works; on failure how to get at JWT body (for logging).

Resolution

You can use another library for Base64Url decoding from a scripting filter.

For example API Gateway already has the Nimbus Jose Jars loaded (com.nimbusds.jose.util.Base64URL), or use Java's java.util.Base64.getUrlDecoder().

See attached policy export for a working example.


JavaScript scripting filter:
function invoke(msg)        
{
   var base64URLEncodedData = msg.get("tokenpart");

   //break on '.' and get 2nd part; assumes three part JWT like: something.something.something
   var arrayJWT = base64URLEncodedData.split(".");
   if (arrayJWT.length < 2)
      return false;
   var secondJWTPart = arrayJWT[1];

   //Using JOSE, a bit simpler
   var dataDecoded = (new com.nimbusds.jose.util.Base64URL(secondJWTPart)).decodeToString();
   msg.put("decoded.fullString", dataDecoded);

   //Alternate, using Java util decoder, don't forget byte[] and encoding
   var tmpByteArray = java.util.Base64.getUrlDecoder().decode(secondJWTPart);
   var dataDecoded2 = new java.lang.String(tmpByteArray, "UTF-8");
   msg.put("decoded2.fullString", dataDecoded2);

  //see attached policy for example on parsing a field like iss from the JSON.

   return true;         
}