I need to set a custom soap header attribute on a jax-ws generated webservice client. I my case all webservice calls must go through a proxy server requiring a specific token (recieved from the web request header) to be present in the soap request header. E.g.:
1 CarServiceService service = null;
2 service = new CarServiceService(new URL(url), new QName(qname);
3 CarServiceEndpoint port = service.getCarServicePort();
It seems that in line 3 the wsdl is retrieved and my call fails due to the missing security token. Could any one point to direction on how this is done?
A detailed example has been mentioned here:
Creating and Deploying JAX-WS web service on Tomcat 6
This article shows how to create and use security token.
I was able to resolve my issue from this blog post: http://tugdualgrall.blogspot.dk/2009/02/jax-ws-how-to-configure-service-end_17.html
Basically I needed to set the webservice endpoint manually instead of the framework trying to extract the endpoint from the requested wsdl - which failed.
Related
I have created a SOAP web-service, running in a tomcat container, using CXF and a WSDL contract approach. The Java code was generated from the WSDL using the maven plugin "cxf-codegen-plugin".
Now, I would like to also expose the web-service as a custom HTTP / JSON web-service by mapping the XML data into JSON data. But I haven't been successful yet and I would appreciate any help to achieve that.
I found that old documentation https://cxf.apache.org/docs/json-support.html on CXF's website (which has also been recently duplicated and not corrected here https://cwiki.apache.org/confluence/display/CXF20DOC/JSON+Support). I got it running with a small fix : sf.setBindingId(HTTPBinding.HTTP_BINDING); instead of sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); since HttpBindingFactory does not exist anymore in CXF 3.x versions.
The first issue with that solution is that it depends on jettison-json whose last release was published in July 2016. The project looks dead. I could not find any suitable replacement. I only found StAXON which is worst : last release in February 2014.
Is there any other library that is well maintained and that implements StAX ?
The second issue is that the example uses a server bean while I already have a container. For the SOAP service, I simply use the public static Endpoint publish(String address, Object implementor) function.
How can I use both the Tomcat container and the JSON/XML conversion ?
The third issue is that I could not send a valid JSON request so far. The absence of documentation does not help. Still, I managed to get as far as sending a valid JSON equivalent of the SOAP header content. But I could not manage to guess how to make CXF also reads the equivalent of the SOAP body. The Java interface of the web-service is public Response get(Header header, Body body); and I keep getting errors : org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking public abstract Response ServicePort.get(Header,Body) with params [Header#88f6973[user=bbcc2545-27ea-43cd-a1fe-c4a194258e0f]]. Obviously the body is missing.
Is there anyone who knows the right JSON syntax to send a request to a CXF HTTP / JSON web-service that relies on jettison-json ? (Or where could one find a comprehensive documentation ?)
Last year I made JAX-WS client for a web service in this link
This webservice use a STS service to get SAML token and use it to access main webservice. I use wsdl2java of apache cxf to generate JAX-WS client for this webservice. Everything was just fine.
Recently they have updated their STS service endpoint. This new STS service endpoint. Which has different signature and digest algorithm. It has some extra element in request body.
I tried to modify current code so that it support new STS service. But my code is sending same RequestSecurityToken request.I mean it does not adopt for new requirement. I tried to adopt this but I could not do that.
New STS service required http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 as new signature method and http://www.w3.org/2001/04/xmlenc#sha256 as new digest algorithm. Plus it required following element in request body:
<tr:ActAs xmlns:tr="http://docs.oasis-open.org/ws-sx/ws-trust/200802">
<v13:RelationshipToken xmlns:v13="http://vanguard.business.gov.au/2016/03" ID="1bc9a44e-dccd-49e2-8f29-40d7b1257325">
<v13:Relationship v13:Type="OSPfor">
<v13:Attribute v13:Name="SSID" v13:Value="1234567895"/>
</v13:Relationship>
<v13:FirstParty v13:Scheme="uri://abr.gov.au/ABN" v13:Value="27809366375"/>
<v13:SecondParty v13:Scheme="uri://abr.gov.au/ABN" v13:Value="89567587874"/>
</v13:RelationshipToken>
</tr:ActAs>
Plus there are minor differences here. I have two ways now I think:
If I can change old code to STS client send request with those value. which I tried and not succeeded.
They provide some code which support fetching SAML assertion token and proof token from STS client. If I can put SAML assertion token into my JAX-WS client directly then this problem is also solved.
Any help or suggestion will be appreciated to us
The SHA-256 digest algorithm is normally set by using an AlgorithmSuite policy that requires it (e.g. Basic256Sha256). I see in the policy they are still using "Basic256" however. CXF allows you to configure RSA-SHA256 via some configuration properties (see for example 'ws-security.asymmetric.signature.algorithm' here http://cxf.apache.org/docs/ws-securitypolicy.html). You can set ActAs Object/Element on the STSClient directly.
I was receiving "An error occurred when verifying security for the message". Two changes that I had to make to resolve this while using Metro 2.3.1 -
In the STS wsdl, need to mention the signature algorithm like this ---
sp:AlgorithmSuite signatureAlgorithm="SHA256withRSA"
In the USI wsdl, need to change the AlgorithmSuite to Basic256 from Basic256Sha256Rsa15
I have a jax-ws web service deployed on web sphere server and when I am trying to access the wsdl in browser with the url
"Http://localhost:7001/HelloWorldService/port/helloworld?wsdl"
I see that the url is getting changed to the below one
"Http://localhost:7001/HelloWorldService/port/helloworld/HelloWorldService.wsdl"
Can someone explain the difference between these both .wsdl and ?wsdl and what needs to be done to keep the url same as ?wsdl instead of getting changed to .wsdl?
helloworld?wsdl --> is just a request to the service provider so you can get the wsdl.
HelloWorldService.wsdl" --> This is the actual file that describes the service which has set of endpoints.
I am building Java application for Online Web Services and let's call it application A . I got the WSDL file form the second party so I can communicate with their application and let's call it application B.
From the WSDL file I generate the Java classes needed which are Requests and Responses classes. Application A will send some request object after setting the needed parameters and excepting response object from application B.
The connection is established and both applications A and B are communicating with each other.
Question:
From application A how can I get the xml data(file or text) for the request object before sending it to application B?
As described the connection is done by passing Java object as request and I know that in some point this request will be converted to xml file. How to get it?
--- EDIT ----
Important Information is missing that may cause confusion.
I am generated the Java Classed have been generated using Axis framework
I don't have much reputation to post a comment, so here is my answer: If you aren't yet using some framework use Apache CXF, If you want to capture the request before sending it application , you can either use cxf interceptors there are some inbuilt interceptors which can do this or you can create a custom interceptor with correct phase ( e.g. post marshal)
The problem is solved by adding the following statements in the bindingStub class that has been auto generated from the WSDL file for the web-services you are trying to access.
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
These statements should be placed after the following method call _call.invoke otherwise you will get NullPointerException .
_call is a variable of type org.apache.axis.client.Cal and it is auto generated by Axis
I'm using CXF to to communicate with a WSDL made in WCF. The WCF side of things was created following a tutorial. The Java code has been generated using a Maven script.
I have gotten things working using HTTPS for encryption. I have gotten authentication working. However, I would like to have the WSDL metadata turned off on the WCF side and still be able to use the Java side to talk to the service.
Currently, I can access the service with metadata publishing on from the Java side using this code:
URL wsdlLocation = new URL("https://server.com:7010/Hservice?wsdl");
HttpsURLConnection connection = (HttpsURLConnection) wsdlLocation.openConnection();
HService service = new HService(wsdlLocation);
HAdminService calc = service.getHAdminService();
... (authentication using WSS4JOutInterceptor code and unrelated code here)
System.out.println(calc.add(new Double(5), new Double(5)));
However, when I turn off metadata publishing on the WCF side I get this error:
Exception in thread "main" javax.xml.ws.WebServiceException:
org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:90)
at javax.xml.ws.Service.<init>(Service.java:56)
at com.blah.hservice.v_1_0.HService.<init>(HService.java:49)
at Main.main(Main.java:85)`
The page the wsdl is on displays this with metadata publishing turned off (this is an excerpt):
This is a Windows© Communication Foundation service.
Metadata publishing for this service is currently disabled.
If you have access to the service, you can enable metadata publishing by completing the following steps to modify your web or application configuration file:
I expected to be able to search "CXF metadata unpublished" and see lots of people doing this...but have not found anything. How do I communicate with this service without the WSDL being published?
You really have two options:
Copy the wsdl locally and point the client at the local wsdl. This is likely the "best" option as it makes sure all the information in the wsdl (like policies and such) is used.
Use "null" for the wsdl location (note: not JAX-WS portable). You will need to call service.addPort(....) after creating the service and before calling getHAdminService to add the port with the appropriate binding and endpoint address. CXF can work most of the time without the WSDL (will internally generate what is needed from the annotations). However, if things like policies are defined in the WSDL, then it cannot.
I got this to work with Client code I generated using CXF 2.6.5
Make sure the QName(first argument) matches the QName the getHAdminService() method references. The bindingId(second argument) should be one of the constants defined in SOAPBinding Interface (javax.xml.ws.soap.SOAPBinding).