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;
}