1
votes

I tried to implement the steps given in WSO2 3.1.0 documentation (https://apim.docs.wso2.com/en/3.0.0/learn/api-gateway/passing-end-user-attributes-to-the-backend/passing-enduser-attributes-to-the-backend-using-jwt/) for customizing JWT.

As given in the documentation, I created the custom JWT generator java class, generated the jar and placed it under WSO2 Home/repository/components/lib folder. Did the necessary configurations in deployment.toml for enabling JWT and restarted the server.

When i hit an API with the bearer token, i am getting the X-JWT-Assertion header in the carbon logs but when i decode it, it doesn't contain the custom claims that i added in the custom JWT generator java class.

It contains the standard claims as seen in the below image and not the custom claims that were added (current_timestamp, message).

Need suggestions on this as i have followed the steps given in the documentation.

enter image description here

4
Hi Suman, is your Custom JWT Generator jar also deployed successfully in <WSO2 Home>/repository/components/dropins folder?Tharika Madurapperuma
Hi Tharika, I have placed the jar only under <WSO2 Home>/repository/components/lib as given in the documentation. Do, I need to place it under <WSO2 Home>/repository/components/dropins folder as well?Suman
Hi Suman, placing the jar under plugins should automatically deploy it under dropins folder. Do you see the jar in the dropins folder?Tharika Madurapperuma
Hi Tharika, I verified, after placing the jar under lib and on restarting the server, it also comes under dropins folder automatically. But, the issue is there and the custom claims don't appear in the X-JWT-Assertion header. And you have mentioned plugins folder above. I guess you are talking about lib folder.Suman
Hi Suman, yes sorry I was talking about the lib folder.Tharika Madurapperuma

4 Answers

1
votes

I have kept the default JWT properties and values that come predefined with the product as is and have added the one you told. Placed the CustomGatewayJWTGenerator jar in the dropins folder. The JWT properties look as below now in deployment.toml. Please let me know if the configurations shown below are correct.

[apim.jwt]

enable = true

encoding = "base64" # base64,base64url

generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"

claim_dialect = "http://wso2.org/claims"

header = "X-JWT-Assertion"

signing_algorithm = "SHA256withRSA"

enable_user_claims = true

claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"

[apim.jwt.gateway_generator]

impl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"

Restarted the server and now when i test the API with JWT access token, the invocation fails and getting null pointer exception. Error Details are as shown below:

ERROR {org.apache.synapse.transport.passthru.ServerWorker} - Error processing GET request for : /pizzashack/1.0.0/menu. java.lang.NullPointerException at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken_aroundBody2(JWTValidator.java:353) at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken(JWTValidator.java:336) at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate_aroundBody0(JWTValidator.java:319) at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate(JWTValidator.java:110) at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate_aroundBody4(OAuthAuthenticator.java:334) at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:109) at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate_aroundBody42(APIAuthenticationHandler.java:419) at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate(APIAuthenticationHandler.java:413) at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest_aroundBody36(APIAuthenticationHandler.java:349) at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:320) at org.apache.synapse.rest.API.process(API.java:367) at org.apache.synapse.rest.RESTRequestHandler.apiProcessNonDefaultStrategy(RESTRequestHandler.java:149) at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:95) at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:71) at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:327) at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:98) at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180) at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:368) at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:189) at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:813)

1
votes

After some research I found out it is a OSGi bundle that runs on top of Apache Felix.

Please check following import available in sample code (CustomGatewayJWTGenerator):

import org.osgi.service.component.annotations.Component;

See also sample pom.xml. It adds some information about OSGi bundle:

Here is the important part:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>3.2.0</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Bundle-Name>${project.artifactId}</Bundle-Name>
            <Export-Package>
                org.wso2.carbon.test.*
            </Export-Package>
            <Import-Package>
                org.wo2.carbon.apimgt.gateway.*,
                org.wso2.carbon.apimgt.impl.*
                com.nimbusds.jwt.*,
                *;resolution:=optional
            </Import-Package>
        </instructions>
    </configuration>
</plugin>

As you can see, it exports components as OSGi. See bellow my pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.wso2</groupId>
        <artifactId>wso2</artifactId>
        <version>1.2</version>
    </parent>
    <groupId>org.example</groupId>
    <artifactId>CustomGatewayJWTGenerator</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>bundle</packaging>
    <dependencies>
        <dependency>
            <groupId>org.wso2.carbon.apimgt</groupId>
            <artifactId>org.wso2.carbon.apimgt.gateway</artifactId>
            <version>${carbon.apimgt.version}</version>
        </dependency>
        <dependency>
            <groupId>org.wso2.orbit.com.nimbusds</groupId>
            <artifactId>nimbus-jose-jwt</artifactId>
            <version>7.3.0.wso2v1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>3.2.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Name>${project.artifactId}</Bundle-Name>
                        <Export-Package>
                            la.foton.wso2.apim.custom.*
                        </Export-Package>
                        <Import-Package>
                            org.wo2.carbon.apimgt.gateway.*,
                            org.wso2.carbon.apimgt.impl.*
                            com.nimbusds.jwt.*,
                            *;resolution:=optional
                        </Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <carbon.apimgt.version>6.6.163</carbon.apimgt.version>
    </properties>
</project>

I believe you just need to change package information in <Export-Package>, copy JAR file to $APIM_HOME/repository/components/dropins and restart server.

Please let me know if something goes wrong. If it works, please mark answer as correct to help others. :)

0
votes

I tried to reproduce this scenario locally. It was reproducible when we are using JWT access tokens to invoke the API.

But I was able to successfully get the custom claims in the X-JWT-Assertion header when using OAuth tokens. Please see the below image.

enter image description here

You need to follow this documentation to do the customisation when using JWT access tokens to invoke the API.

0
votes

I followed the documentation that you shared for invoking the API with JWT access token. I cloned the GIT repository given in the doc.: https://github.com/wso2/samples-apim/tree/master/CustomGatewayJWTGenerator, imported the CustomGatewayJWTGenerator code into eclipse. After the import was successful, i could see a build path error in eclipse: joda-time-2.9.4.wso2v1.jar' in project 'CustomGatewayJWTGenerator' cannot be read or is not a valid ZIP file. Even though the error was seen in eclipse, i was able to build the jar using Maven. I placed the generated jar in lib folder and after server restart verified that the jar was present in dropins folder as well. But somehow, the custom claims that i added in the CustomGatewayJWTGenerator java class are still not coming in the X-JWT-Assertion header. Is it something to do with the error that i got in eclipse after importing the CustomGatewayJWTGenerator project or am i going wrong somewhere else?

The CustomGatewayJWTGenerator java class: enter image description here

X-JWT-Assertion header: enter image description here