Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Custom JWT Generator in WSO2 API Manager

DZone 's Guide to

Custom JWT Generator in WSO2 API Manager

Create a custom JWT generator with WSO2 API Manager (2.6.0)

· Security Zone ·
Free Resource

This is yet another article on generating custom JWT in WSO2 API Manager. For details please read the official documentation.

Software

For this tutorial, you will only need the following product.

  • WSO2 API Manager (2.6.0)

Make sure that you have Java installed in your system.

Creating a Maven Project

Let's create a very simple Maven project. Here is the pom.xml of the project.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.anupam.jwt</groupId>
    <artifactId>MyJWTGenerator</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <name>MyJWTGenerator</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <dependency>
            <groupId>org.wso2.carbon.apimgt</groupId>
            <artifactId>org.wso2.carbon.apimgt.keymgt</artifactId>
            <version>6.1.66</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <repositories>
        <repository>
            <id>wso2-nexus</id>
            <name>WSO2 internal Repository</name>
            <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
                <checksumPolicy>ignore</checksumPolicy>
            </releases>
        </repository>
    </repositories>
</project>


Custom JWT Generator

To create a custom JWT generator, you will need to create a class extending the following superclass.

org.wso2.carbon.apimgt.keymgt.token.AbstractJWTGenerator


In this tutorial, I am going to add three extra claims (access_token, prop_1 & prop_2)  to the JWT, along with the default claims of WSO2 API Manager. Here is the custom JWT generator class.

package com.anupam.jwt;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.token.ClaimsRetriever;
import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext;
import org.wso2.carbon.apimgt.keymgt.token.AbstractJWTGenerator;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;

public class MyJWTGenerator extends AbstractJWTGenerator {

    private static final Log log = LogFactory.getLog(MyJWTGenerator.class);

    public MyJWTGenerator() {
    }

    public Map<String, String> populateStandardClaims(TokenValidationContext validationContext) throws APIManagementException {
        Map<String, String> claims = new LinkedHashMap(20);
        return claims;
    }

    public Map<String, String> populateCustomClaims(TokenValidationContext validationContext) throws APIManagementException {
        ClaimsRetriever claimsRetriever = this.getClaimsRetriever();
        String tenantAwareUserName = validationContext.getValidationInfoDTO().getEndUserName();
        SortedMap<String, String> map = claimsRetriever.getClaims(tenantAwareUserName);
        map.put("access_token", validationContext.getAccessToken());
        map.put("prop_1","Property One");
        map.put("prop_2","Property Two");
        return map;
    }
}


Packing the Class

Generate a jar file.

$ mvn clean install


Copy the jar file and put it in the following directory of WSO2 API Manager.

$ wso2am-2.6.0/repository/components/lib


Configure the Custom JWT Generator 

Here is the basic configuration you will need for the custom JWT generator to work in WSO2 API Manager.

Configuration in api-manager.xml

Edit the following information in the api-manager.xml of WSO2 API Manager; it's a mandatory configuration.

wso2am-2.6.0/repository/conf/api-manager.xml

<JWTConfiguration>
        <!-- Enable/Disable JWT generation. Default is false. -->
        <EnableJWTGeneration>true</EnableJWTGeneration>

        <!-- Name of the security context header to be added to the validated requests. -->
        <JWTHeader>X-JWT-Assertion</JWTHeader>

        <!-- Fully qualified name of the class that will retrieve additional user claims
             to be appended to the JWT. If not specified no claims will be appended.If user wants to add all user claims in the
             jwt token, he needs to enable this parameter.
             The DefaultClaimsRetriever class adds user claims from the default carbon user store. -->
        <ClaimsRetrieverImplClass>org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever</ClaimsRetrieverImplClass>

        <!-- The dialectURI under which the claimURIs that need to be appended to the
             JWT are defined. Not used with custom ClaimsRetriever implementations. The
             same value is used in the keys for appending the default properties to the
             JWT. -->
        <ConsumerDialectURI>http://wso2.org/claims</ConsumerDialectURI>

        <!-- Signature algorithm. Accepts "SHA256withRSA" or "NONE". To disable signing explicitly specify "NONE". -->
        <!--SignatureAlgorithm>SHA256withRSA</SignatureAlgorithm-->

        <!-- This parameter specifies which implementation should be used for generating the Token. JWTGenerator is the
     default implementation provided. -->
        <JWTGeneratorImpl>com.anupam.jwt.MyJWTGenerator</JWTGeneratorImpl>

        <!-- This parameter specifies which implementation should be used for generating the Token. For URL safe JWT
             Token generation the implementation is provided in URLSafeJWTGenerator -->
        <!--<JWTGeneratorImpl>org.wso2.carbon.apimgt.keymgt.token.URLSafeJWTGenerator</JWTGeneratorImpl>-->

    </JWTConfiguration>


Note that in JWTGeneratorImpl, we have referred to our custom JWT generator class.

Configuration in log4j.properties File

This is an optional configuration and should not be done in the production environment. Add this property in the log4j.properties file.

wso2am-2.6.0/repository/conf/log4j.properties

log4j.category.org.apache.synapse.transport=DEBUG


Testing

Start the WSO2 API Manager.

$ sh wso2server.sh


Open https://localhost:9443/carbon, and let's fill the default claim values of the admin user as shown below.

Updating Profile: admin

Now, deploy the PizzaShack sample API, and let's make a call to any of its resources. In the log, you should see the JWT in the header X-JWT-Assertion we configured in the api-manager.xml file.

X-JWT-Assertion

Let's copy the value and decode it in https://jwt.io/

Here is the decoded token.

{
  "http://wso2.org/claims/organization": "WSO2",
  "http://wso2.org/claims/role": [
    "Internal/subscriber",
    "Internal/creator",
    "Application/admin_DefaultApplication_PRODUCTION",
    "Internal/publisher",
    "Internal/everyone",
    "admin"
  ],
  "http://wso2.org/claims/mobile": "1111111111",
  "prop_1": "Property One",
  "http://wso2.org/claims/givenname": "Administrator",
  "prop_2": "Property Two",
  "access_token": "e9c342e1-f079-3e37-8c4c-7bc629a60850",
  "http://wso2.org/claims/telephone": "1111111111",
  "http://wso2.org/claims/im": "admin.admin",
  "http://wso2.org/claims/country": "Brazil",
  "http://wso2.org/claims/emailaddress": "admin@carbon.super",
  "http://wso2.org/claims/lastname": "Administrator",
  "http://wso2.org/claims/url": "http://www.porua.com"
}


You can check the extra claims (access_token, prop_1, and prop_2) along with the default claims. This JWT will be passed to the backend implementation of the API in the X-JWT-Assertion header and the backend can extract information from the JWT for farther validation.

Debugging 

Debugging is the best way to understand what goes under the hood. Use the IntelliJ IDE (my preference) and create a remote debugging configuration as shown below.

IntelliJ IDE

Stop the WSO2 API Manager and restart it with the debug mode enabled.

$ sh wso2server.sh -debug 5000


Put some debug points in the custom JWT generator class. Once you make a request to the PizzaShack API, you should be able to enter in the debug points.

Conclusion

This is a simple custom JWT generator class that I described in the article. This tutorial is completely based on API Manager 2.6.0. If the same custom JWT generator is created for a different version of API Manager, it might not work due to dependency.

Thanks for reading, and please let me know if you could create one.

Topics:
wso2 api manager ,jwt ,json ,tutorial ,security ,tutorial.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}