How to write a custom Class Mediator to decode a JWT value

Naduni Pamudika
API Integration Essentials
2 min readJul 7, 2018

In this blog post I will guide you through how to write a custom class mediator and how to use the class mediator in sequences in WSO2 API Manager.

Implementing the Class Mediator

Here I have created a Java Maven project called jwt-decode-mediator using IntelliJ Idea. You can use any other Java IDE like Eclipse to implement this.

First add the following dependency in the pom.xml as below.

<dependency>
<groupId>org.apache.synapse</groupId>
<artifactId>synapse-core</artifactId>
<version>2.1.7-wso2v65</version>
<exclusions>
<exclusion>
<groupId>org.apache.axis2</groupId>
<artifactId>addressing</artifactId>
</exclusion>
</exclusions>
</dependency>

Then implement the JwtDecodeMediator class like this. Here you can either implement the Mediator class or extend the AbstractMediator class.

You can find the full source code at GitHub.

public class JwtDecodeMediator extends AbstractMediator {

private static final Logger log = LoggerFactory.getLogger(JwtDecodeMediator.class);

private String jwtHeader;
private String accountIds;

private static String retrieveAccountId(String accountRequestInfo) {
String[] split_string = accountRequestInfo.split("\\.");
String base64EncodedBody = split_string[1];

Base64 base64 = new Base64();
try {
String decodedString = new String(base64.decode(base64EncodedBody.getBytes()));
JSONParser parser = new JSONParser();
JSONObject accountRequestInfoJson = (JSONObject) parser.parse(decodedString);
if (accountRequestInfoJson.containsKey("accountRequestIds")) {
JSONArray accountRequestIdsArray = (JSONArray) accountRequestInfoJson.get("accountRequestIds");
String[] accountIdsArray = new String[accountRequestIdsArray.size()];
JSONObject accountRequestId;
for (int i = 0; i < accountRequestIdsArray.size(); i++) {
accountRequestId = (JSONObject) accountRequestIdsArray.get(i);
accountIdsArray[i] = accountRequestId.get("accountId").toString();
accountIdsArray[i] = accountIdsArray[i].split("\\[")[1].split("\\]")[0];
}
String accountIds;
accountIds = String.join(",", accountIdsArray);
return accountIds;
} else {
if (log.isDebugEnabled()) log.error("Account Request Ids is not available");
}
} catch (ParseException e) {
log.error("Error in passing Account-Request-Information " + e.toString());
}
return null;
}

@Override
public boolean mediate(MessageContext mc) {
accountIds = retrieveAccountId(getJWT_HEADER());
mc.setProperty("accountIds", accountIds);
log.info("--------------------ACCOUNT_IDs--------------------" + accountIds);
return true;
}

public String getJWT_HEADER() {
return jwtHeader;
}

public void setJWT_HEADER(String jwtHeader) {
this.jwtHeader = jwtHeader;
}

public String getAccountIds() {
return accountIds;
}

public void setAccountIds(String accountIds) {
this.accountIds = accountIds;
}
}

Here I have tried to decode the JWT and extract the AccountId fields from a JSON payload. Sample Json payload would look like this.

{
"accountRequestIds": [
{
"accountId": [
"34568"
],
"transactionFromDateTime": "2017-06-26T12:00:00+05:30",
"transactionToDateTime": "2019-06-27T12:00:00+05:30",
"permissions": [
"ReadAccountsDetail",
"ReadBalances"
]
},
{
"accountId": [
"41825"
],
"transactionFromDateTime": "2017-06-26T12:00:00+05:30",
"transactionToDateTime": "2019-06-27T12:00:00+05:30",
"permissions": [
"ReadAccountsDetail",
"ReadBalances"
]
}
]
}

Deploying the Class Mediator

In order to deploy the custom class mediator, first build your Maven project using maven clean install. It will create a jar file at the target directory. You can simply put the jar file into <APIM_HOME>/repository/components/lib folder to deploy the class mediator.

Now you can use the class mediator at your mediation sequences to decode the JWT value.

Accessing Values in a Mediation Sequence

You can use the class mediator to decode a JWT value like this. When you give the class mediator name, make sure to give the fully qualified name of the class as <package_name>.<class_name>.

<?xml version="1.0" encoding="UTF-8"?>
<sequence
xmlns="http://ws.apache.org/ns/synapse"
name="AccountsInfo--In">
<class name="org.wso2.apim.JwtDecodeMediator">
<property name="JWT_HEADER" expression="$trp:Account-Request-Information"/>
</class>
<log level="custom">
<property name="IN_SEQUENCE_BULK_ACCOUNTS_DETAILS_ACCOUNT_IDs" expression="get-property('accountIds')"/>
</log>
</sequence>

When executing the sequence, you can see the account Ids printed in the console as below.

"34568","41825"

References

[1]https://docs.wso2.com/display/EI620/Class+Mediator

[2]https://docs.wso2.com/display/ESB500/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java

--

--

Naduni Pamudika
API Integration Essentials

Associate Technical Lead @ WSO2 | Graduate from the Department of Computer Science & Engineering, University of Moratuwa