apim
2022/07/20
 
20 Jul, 2022 | 3 min read

Generate Customized Tokens in WSO2 API Manager

  • Hisan Hunais
  • Senior Software Engineer - WSO2

Photo by Markus Spiske on Unsplash

There are two types of tokens which can be generated when invoking the token endpoint in WSO2 API Manager. They are Opaque tokens and JWT tokens. You can easily create a service provider through the Management console and select which type of token you wish to generate using the service provider. What if you want the generated tokens to be in a customized format? In this article, we will look at how to create our own token issuer and generate customized tokens.

Background

First, let’s look at the structure of the existing token issuer classes. OauthTokenIssuer is the interface that contains the definitions of the methods which are used for token generation related functions. OauthTokenIssuerImpl is the class which generates the UUID based tokens (Opaque tokens) by implementing the relevant methods of the OauthTokenIssuer interface. The JWT tokens are generated using the JWTTokenIssuer class which overrides the accessToken() method by extending the OauthTokenIssuerImpl class.

These classes can be used as extension points to add the customized implementation. In this article, I will show a scenario where we prepend the “custom_” string to the UUID based tokens. To explain, I will be using WSO2 API Manager 4.1 to show this scenario.

Writing the Custom Token Issuer

First, we need to write our custom token issuer. Start by creating a new maven project called CustomTokenIssuer, and add the <parent>, <dependencies>, <repositories> and <pluginRepositories> tags to the pom.xml as shown in the code segment below. 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example </groupId>
<artifactId>CustomTokenIssuer</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.wso2</groupId>
<artifactId>wso2</artifactId>
<version>1.3 </version>
</parent>

<dependencies>
<dependency>
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
<artifactId>org.wso2.carbon.identity.oauth</artifactId>
<version>6.4.176</version>
</dependency>
</dependencies>

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

<pluginRepositories>
<pluginRepository>
<id>wso2.releases</id>
<name>WSO2 internal Repository</name>
<url>https://maven.wso2.org/nexus/content/repositories/releases/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</pluginRepository>
<pluginRepository>
<id>wso2.snapshots</id>
<name>WSO2 Snapshot Repository</name>
<url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>wso2-nexus</id>
<name>WSO2 internal Repository</name>
<url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</pluginRepository>
</pluginRepositories>
</project>

We add the org.wso2.carbon.identity.oauth dependency as it contains the classes which are related to the token generation functionality. After adding the changes, build the project using mvn clean install to download the relevant dependencies.

Next, create a package called org.example.issuer, under src/main/java and create a Java class called CustomTokenIssuer within the newly created package. The directory structure will look something like Figure 1 below.

Figure 1: Directory structure for our custom implementation

For our scenario of prepending the “custom_” string to UUID based tokens, we could extend the functionality of the OauthTokenIssuerImpl class since this type of class already has the implementation for generating UUID based tokens. We simply need to override the accessToken() and refreshToken() methods and add our custom implementation. Within the custom implementation, we could call the super class methods to generate the UUID based tokens and add the “custom_” string to the returned values. The CustomTokenIssuer.java class containing the custom implementation is shown in the following code segment.

package org.example.issuer;

import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.identity.oauth2.token.OauthTokenIssuerImpl;

public class CustomTokenIssuer extends OauthTokenIssuerImpl {

public CustomTokenIssuer() {

}

@Override
public String accessToken(OAuthTokenReqMessageContext tokReqMsgCtx) throws OAuthSystemException {
String uuidToken = super.accessToken(tokReqMsgCtx);
return "custom_" + uuidToken;
}

@Override
public String refreshToken(OAuthTokenReqMessageContext tokReqMsgCtx) throws OAuthSystemException {
String uuidToken = super.refreshToken(tokReqMsgCtx);
return "custom_" + uuidToken;
}
}

Similarly, you can override the accessToken() and refreshToken() methods and add your own implementation. We can now build the project using mvn clean install and the generated jar can be found in the /target directory as CustomTokenIssuer-1.0-SNAPSHOT.jar.

Adding the Custom Functionality to the API-M Pack

Next let’s see how we can include this to our API-M pack. We need to add the generated jar to the <API-M_HOME>/repository/components/lib directory. Also, we need to add the following configuration in the <API-M_HOME>/repository/conf/deployment.toml file.

[[oauth.extensions.token_types]]

name="Custom"

issuer="org.example.issuer.CustomTokenIssuer"

You can give any name to the new type of tokens and this value will be the display name in the management console when selecting the Token Issuer for a service provider. The issuer is the class name along with the package name in which the custom implementation was done.

Now, let’s start the APIM pack to check this behavior. Once the APIM instance begins, login to the management console and create a service provider. When configuring the OAuth/OpenID Connect Configuration, select “Custom” as the token issuer as shown below in Figure 2.

Figure 2: Token Issuer options including “Custom” 

Next, let’s generate the tokens using this service provider.

  1. Get the base64 encoded value of <clientID:clientSecret> of the service provider.
  2. Now, using the password grant, generate the tokens by invoking the /oauth2/token endpoint. The screen should look similar to Figure 3 below.

Figure 3: Output obtained when the token endpoint is invoked

As you can see from the above figure, the generated access token and refresh token have the “custom_” string prepended to a UUID based token. This confirms the tokens were generated using the newly introduced Custom Token Issuer.

Similarly, we can use the refresh grant to generate new tokens by providing the custom refresh token which was generated. The screen should look similar to Figure 4 below.

Figure 4: Output obtained when the token endpoint is invoked using the refresh token grant

Conclusion

In WSO2 API Manager, you can generate Opaque and JWT tokens by invoking the token endpoint. There may be scenarios where you need custom tokens to be managed in your own way. I hope this article will help guide you to create custom tokens for your future requirements. 

If you'd like to find out more, learn the basics of OAuth 2.0.
English