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.
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. :)
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)
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.
You need to follow this documentation to do the customisation when using JWT access tokens to invoke the API.
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:
X-JWT-Assertion header:
Related
I have spent five days trying to get a simple HelloWorld web service to work in IntelliJ and this is my last chance to get it to work.
I am still very much a beginner in Web Services especially with Java, so please bare with me.
I have raised several tickets with JetBrains complaining about the outdated and vague documentation, the guys have been very helpful but have acknowledged there is a limitation, that it's not as straight forward to setup & the documentation is in fact outdated.
I am not getting a proper clean solution.
I was wondering if anyone uses the latest version of IntelliJ to build web services?
I am using Wildly, JBoss as the application server
I asked if I should be creating a Web App or a Rest Service as there is no user interaction since it will be a pure Web Service.
I have been advised to use a Rest Service, But I have created it both ways & attached the screenshots where applicable.
As a REST Service:
A simple project with one Web Service and a Web Method which returns a simple string:
Create a new project, choose Web App or Rest Service?
Choose XML Web Services? With CXF Implementation?
This is where I am a bit confused.
According to this link: https://developer.jboss.org/message/799428#799428
JBoss comes with its own implementation of Web Services JBossWS & It is recommended to use that instead of external Apache CXF?
So I'm not sure if I need to do anything, in this case it should work out of the box,
but it simply does not as I am getting exceptions:
This is the simple Project structure:
I have a basic web service class with the #WebService annotation:
package com.testwebservices.MyFirstWebService;
import javax.jws.WebService;
#WebService
public class MyFirstWebService {
public String firstWebMethod(){
return "Mama is the best!";
}
}
Now I am trying to expose this as a web service but its just not happening:
Now I am getting these options, If I choose anything other than the default Apache Axis I get a path incorrect issue,
See screenshot below with Default Apache Axis:
And when I choose CXF:
If JBossWS provides support for this out of the box, should it not work easily? Especially as most IDE's make this easy out of the box.
When I run the project nothing happens, there is no WSDL file, I went to the admin console, no mention of it. The documentation is vague.
As a Web App
When I choose the web app option and follow the same steps as above.
I get this exception:
Caused by: java.lang.ClassNotFoundException: org.apache.axis.transport.http.AxisServlet
What is the best way to setup a Web Services project in intelliJ?
I have no clue how to configure this or set it up.
Any help would be appreciated
I might encourage you to turn it around - use IntelliJ to build but get the general structure right first. Start with the Java code:
HeartBeatService.java
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
#WebService
#SOAPBinding(style = SOAPBinding.Style.RPC)
public class HeartBeatService {
#WebMethod
public HeartbeatResponse getHeartBeat() {
return new HeartbeatResponse("OK");
}
}
HeartbeatResponse.java
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class HeartbeatResponse {
private String status;
public HeartbeatResponse() {
}
public HeartbeatResponse(String status) {
this.status = status;
}
}
a pom.xml using the most recent things I could find:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hotjoe.sample</groupId>
<artifactId>jaxws-super-simple</artifactId>
<name>JAX-WS Integration Example</name>
<version>1.0.0</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</project>
and, lastly, a web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.0">
</web-app>
Put this into a maven structure and make sure it compiles with mvn clean package and then import that into IntelliJ.
This code is derived from my repository at https://github.com/stdunbar/jaxws-sample if you need more details.
I want to test my spring-boot Rest API by using a pact json file provided. The thing is all the resources on internet points to verifying using pact-broker. I will get there but currently, working on a POC for this is turning out to be quite difficult.
No matter what pom configuration, it tries to connect to localhost.
Here's my pom.xml
<plugin>
<groupId>au.com.dius.pact.provider</groupId>
<artifactId>maven</artifactId>
<version>4.1.11</version>
<configuration>
<serviceProviders>
<serviceProvider>
<name>Service</name>
<consumers>
<consumer>
<name>consumer123</name>
<pactSource>/Usr/Pact-JVM-Example/pacts/</pactSource>
</consumer>
</consumers>
</serviceProvider>
</serviceProviders>
<pactBrokerUrl/>
</configuration>
</plugin>
Please note that the json is physically residing on the provided path /Usr/Pact-JVM-Example/pacts/. Also, I've intentionally removed pactBrokerUrl as I am not planning to connect to a remote pact json.
In the end, I want the test to pass/fail on the basis of the json file in /Usr/Pact-JVM-Example/pacts/ when I run ./mvnw pact:verify
Please check the main readme here https://github.com/pact-foundation/pact-jvm/tree/master/provider/maven
This plugin is for verifying a running provider
It always tries to call a localhost server by default. You need Junit4 or Junit5 libraries
I've created with Axis2 XMLBeans (Version 1.6.2) a client to connect some CRM Dynamics webservices. The client works perfectly fine when I launch it as a standalone project, but when I integrate it into the maven structure of the project and I try to consume the service, I get the following error:
ERROR [http-bio-8080-exec-13][render_portlet_jsp:154]
java.lang.ClassFormatError: Incompatible magic value 4022320623 in
class file
schemaorg_apache_xmlbeans/system/sC40263DCBC25A143E59FC252DB52E714/TypeSystemHolder
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at
java.lang.ClassLoader.defineClass(ClassLoader.java:616) at
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at
org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2889)
at
org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1170)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
at
org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(XmlBeans.java:769)
at
com.microsoft.schemas.crm._2007.webservices.RetrieveDocument.(RetrieveDocument.java:19)
at
com.microsoft.schemas.crm._2007.webservices.RetrieveDocument$Factory.newInstance(RetrieveDocument.java:147)
I've created the Axis code who's giving the error via Maven with the following plugin:
<plugins>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.6.2</version>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
<configuration>
<packageName>myPackage</packageName>
<wsdlFile>src/main/resources/CrmService.wsdl</wsdlFile>
<databindingName>xmlbeans</databindingName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Any idea what is happening? The error indicates normally that the class is corrupted, but I've generated several times (and with different versions of Axis2) and the result is the same...
Just find the solution. In order to include the generated classes into the jar, I've added this lines:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>target/generated-sources/axis2/wsdl2code/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>target/generated-sources/axis2/wsdl2code/src</directory>
<filtering>true</filtering>
</resource>
</resources>
After changing the filtering of the resources directory to false, the problem disappears.
I ran into the same problem, I generated an axis 2 client with xmlbeans and when testing it gave me the same error, I looked in many places for a possible solution and this was the only one that worked for me.
The web client is built in a maven module for another web application inside a jar as a dependency.
at the end modifying the pom file to add the filter equal to false it worked
Note: I could not find a straight-forward answer to this problem so I will document my solution below as an answer.
I generated the server-side part of a webservice from a wsdl using Axis 1.4 and
the axistools-maven-plugin. The Axis servlet is mapped to /services/*, the
service is configured in WEB-INF/server-config.wsdd as follows:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="TestService" style="document" use="literal">
<namespace>http://example.com/testservier</namespace>
<parameter name="className" value="com.example.TestServiceImpl"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
</service>
</deployment>
When I deploy this web application to Tomcat and access
http://localhost:8080/testservice/services a list of deployed services is
returned.
And now... Some Services
TestService (wsdl)
TestService
Clicking on wsdl should return the description for this service but results in the following error page:
AXIS error
Could not generate WSDL!
There is no SOAP service at this location
The server-config.wsdd was missing a neccessary configuration setting.
<transport name="http">
<requestFlow>
<handler type="java:org.apache.axis.handlers.http.URLMapper"/>
</requestFlow>
</transport>
It seems the URLMapper is responsible for extracting the service name from
the url, without it axis does not know which service to invoke. This is sort of
documented in the axis faq:
This mechanism works because the HTTP transport in Axis has the URLMapper (org.apache.axis.handlers.http.URLMapper) Handler deployed on the request chain. The URLMapper takes the incoming URL, extracts the last part of it as the service name, and attempts to look up a service by that name in the current EngineConfiguration.
Similarly you could deploy the HTTPActionHandler to dispatch via the SOAPAction HTTP header. You can also feel free to set the service in your own custom way - for instance, if you have a transport which funnels all messages through a single service, you can just set the service in the MessageContext before your transport calls the AxisEngine
This makes it sound like the URLMapper would be configued by default which does not seem to be the case.
When I had this problem, it was caused by using the wrong URL.
I used http://localhost:8080/axis/services/AdminWebService?wsdl instead of http://localhost:8080/axis/services/AdminService?wsdl.
AdminWebService must be changed to AdminService.
You better build the server-config.wsdd automatically with the goal "admin". See the documentation about this plugin:
http://mojo.codehaus.org/axistools-maven-plugin/admin-mojo.html
It is very difficult to generate the server-config.wsdd manually.
Example:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<filename>${project.artifactId}.wsdl</filename>
<namespace>http://server.ws.xxx</namespace>
<namespaceImpl>http://server.ws.xxx</namespaceImpl>
<classOfPortType>XXXWebService</classOfPortType>
<location>http://localhost:8080/XX/services/XXXWebService</location>
<bindingName>XXServiceSoapBinding</bindingName>
<style>WRAPPED</style>
<use>literal</use>
<inputFiles>
<inputFile>${basedir}\src\main\webapp\WEB-INF\xxxx\deploy.wsdd</inputFile>
<inputFile>${basedir}\src\main\webapp\WEB-INF\xxxx\deploy.wsdd</inputFile>
</inputFiles>
<isServerConfig>true</isServerConfig>
<extraClasses></extraClasses>
</configuration>
<executions>
<execution>
<goals>
<goal>java2wsdl</goal>
<goal>admin</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
I had the same problem recently.
Solution :
In my case, I was using Axis 1.4 and was deploying the application on tomcat. However, for some reason the generated server-config.wsdd was not getting packaged in the war and hence was not getting deployed on tomcat. Once, I ensured this is happening, it started working fine for me.
you ensure server-config.wsdd in your package, you can put this file to resources or you can set in your pom.xml via maven which files will be in the package
server-config.wsdd must be valid and correct tags or necessary config is exist so below rows must be in it;
<handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>
<handler type="java:org.apache.axis.transport.local.LocalResponder" name="LocalResponder" />
<transport name="http">
<parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler" />
<parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler" />
<parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler" />
<requestFlow>
<handler type="URLMapper" />
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" />
</requestFlow>
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder" />
</responseFlow>
</transport>
Trying to create some sample prgms using jax-ws.
I am able to successfully generate the required artifacts(java files) and the wsdl file using wsgen. and finally a .war file is generated by maven.
Deployed this .war file in weblogic 9.2 and tried to access the wsdl using the IE browser.But it did not work.
I observed two things
The java and complied class files are generated and are bundled inside the .war file.But the wsdl file is generated outside and not a part of
.war.
Generally wsgen itself will provide the wsdl url.
My queries are:
In order to get the wsdl in IE browser what changes I need to do in POM.
wsdl file should be part of .war.If yes then where should I keep the file.
what changes I need to do to get the soap location url in the wsdl file.
How are you triggering wsgen? It needs to be invoked during the build lifecycle before the war is packaged by Maven. The configuration below will bind the wsgen execution to the process-resources phase, this should mean the wsdl is output below target/classes and included in the war.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<id>wsgen</id>
<phase>process-resources</phase>
<goals>
<goal>wsgen</goal>
</goals>
</execution>
</executions>
<configuration>
...
As far as part 3 of your question, I'm no expert on these things and don't see a means in the plugin to change it. I did find a post that shows how it can be changed programmatically, which may help.