We need to send a SOAP message to a webservice. This is somewhat new territory, so we are a bit confused... even when searching and reading about the subject. Here is what we know / did:
1) We must authenticate through the use of a Digital Certificate in Base64 (obtained issuing a CSR – Certificate Signing Request).
2) The SOAP message must contain a Security Header (wss:Security xmlns:wss="http://schemas.xmlsoap.org/ws/2002/12/secext") and a Body.
3) The WSDL file does not contain a HEADER section, but we have the header "Field structure"
4) We decided to use Axis2/xmlbeans, and created the JAVA classes with https://axis.apache.org/axis2/java/core/tools/eclipse/wsdl2java-plugin.html
5) We can easily create the STUB and send the WSDL body element using the provided sync/async register stub methods (i assume Axis2 will generate the correct SOAP message)
Questions
1) How can we add the WS-Security(?) HEADER to the SOAP message. Do we have to manipulate the AXIS2 generated code?
2) How can we authenticate using the Digital Certificate?
Thanks
1) How can we add the WS-Security(?) HEADER to the SOAP message. Do we have to manipulate the AXIS2 generated code?
ServiceClient client = stub._getServiceClient();
SOAP11Factory factory = new SOAP11Factory();
OMNamespace SecurityElementNamespace = factory.createOMNamespace("http://schemas.xmlsoap.org/ws/2002/12/secext", "wss");
OMElement usernameTokenEl = factory.createOMElement("UsernameToken", SecurityElementNamespace);
OMElement usernameEl = factory.createOMElement("Username", SecurityElementNamespace);
OMElement passwordEl = factory.createOMElement("Password", SecurityElementNamespace);
usernameEl.setText(username);
passwordEl.setText(password);
usernameTokenEl.addChild(usernameEl);
usernameTokenEl.addChild(passwordEl);
SOAPHeaderBlockImpl block = new SOAP11HeaderBlockImpl("Security", SecurityElementNamespace, factory);
block.addChild(usernameTokenEl);
client.addHeader(block);
Related
I wanted to know how I can validate HTTP messages with JWS Detached. Currently, I am receiving x-sign-jws request in header which looks like below
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..UXwjHxU3tFlrzPMupG04zROiEcHFQpCg3l7J4Axr1fE
I need to verify this at my end whether the request is right or not using my secrete Key
Ex: 12345678
I am using firebase/jwt and tried below code
$hed = getallheaders();
$recievedJwt = $hed["X-Sign-Jws"];
$decoded = JWT::decode($recievedJwt, $secret_key, array('JWT','HS256'));```
but I am not getting any result.
I searched on net I found the article which mentioned below steps:
Validation HTTP message with JWS Detached:
a) Get the HTTP header "x-sign-jws",
b) Get BASE64URL HTTP body
c) Put generate string b) into the Payload section
d) Validate JWS
But I am confused with how to get Base64URL HTTP body
Any help would be greatly appreciated since there are only a few articles available on this topic.
JWS format is base64url(header).base64url(payload).base64url(signature), note the dot delimiter between 3 components.
Detached JWS still contains 3 components but the payload is removed and provided elsewhere, usually the payload is provided in the HTTP Body.
To verify detached JWS, you need to add base64url encoded payload to the detached JWS. The payload is available from your HTTP Body.
For example;
x-sign-jws = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..UXwjHxU3tFlrzPMupG04zROiEcHFQpCg3l7J4Axr1fE
//split x-sign-jws into array using delimiter .
x-sign-jws-attached = x-sign-jws-split[0] + '.' + base64Url(HTTPRequest.Body) + '.' + x-sign-jws-split[1]
Now you can verify x-sign-jws-attached as shown below;
$decoded = JWT::decode($x-sign-jws-attached, $secret_key, array('JWT','HS256'));```
I need to consume a WS that requires client (machine) certificate. More precisely it uses WS-Security : SOAP Message Security, WS-Security : X.509 Certificate Token Profile as defined by http://docs.oasis-open.org/wss-m/wss/v1.1.1/os/wss-SOAPMessageSecurity-v1.1.1-os.html
Using the native consumer, Domino don't add (magically) the authentication in the SOAP header. Now how I'm supposed to do add the security in header? Ideally in LotusScript...
I don't see anyway to embed the Consumer in my own header or enrich the existing consumer. I join the IBM response on this.
So my question:
Is there a work around to do this in Lotusscript ?
did some of you done something like this in java (and I will probably make an LS2J since a lot of LotusScript code already exists when I will get (hopefully) the response from the WS
IBM response:
We understand that you are attempting to use SOAP header for authentication. Unfortunately this is currently not supported.
For your reference, we have at least two Enhancement Requests (that I could find in this area) that are related to this topic:
SPR # SODY9H6BTM: Creating Your Own Soap Objects Does Not Support Client Certificate Authentication In A Web Agent.
SPR # JSHN7A3MLP: Authentication data in the Header element of WS Consumer SOAP envelopes
Unfortunately there is nothing further we can do in Support at this time.
If I understood your problem correctly you do not know how to deal with SOAP header and if so there are 2 things you may want to know:
1) Passing session using native Domino consumer approach. See example below
TestServiceLocator service = new TestServiceLocator();
TestPort port = service.getTestPort();
// that would tell to save cookie session between calls
((javax.xml.rpc.Stub)port)._setProperty(javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
2) If it does not work for you, you may try to use native SOAP approach. I've blogged about that recently: SOAP and passing session
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// connect to webserivce
SOAPMessage soapResponse = soapConnection.call(connect(username, password), url);
// read cookie from response and use it when send another requests
MimeHeaders session = soapResponse.getMimeHeaders();
String sesisonCookie = session.getHeader("Set-Cookie")[0];
SOAPMessage soapResponse2 = soapConnection.call(customerGetAll(sesisonCookie), url);
soapConnection.close();
and than imagine you are in customGetAll method
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("Customer_GetAll", "m");
soapMessage.getMimeHeaders().addHeader("Cookie", sesisonCookie);
soapMessage.saveChanges();
Hope it will help.
I need to transform the following json payload into a soap message and send the message to a consumer, the consumer edits the data and sends back the soap message.
I haven't done much in soap. I only have REST experience. what steps do I need to take in a process like this?
what is the best approach?
[{"salesOrderId":"00004-5-6","saleName":"House Sale","status":"processing"}, {"salesOrderId":"00001-2-3","saleName":"Car Sale","status":"processing"}]
There are various way to perform this transformation, for example:
PATH - 1
Json To XML (with transformer or string set payload)
Xml To SOAP Request using XSLT, transformer or string set payload.
Send SOAP Request sobre HTTP (POST / Content-type: applicacion/xml / soapAction)
PATH - 2
Json To SOAP Request using Groovy, XSLT or string set payload.
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
PATH - 3
Json To SOAP Request Proxy (WSDL To Java).
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
The easiest way of doing it is extract the JSON elements from the JSON payload by using <json:json-to-object-transformer/>and store each node value in variables like flow variable in Mule.
Then You can create the SOAP request using XSLT and passing the flow variables value into XSLT as <mulexml:context-property/>
ref:- https://developer.mulesoft.com/docs/display/current/XSLT+Transformer
Once your SOAP XML is created, you can simply post them to your HTTP outbound endpoint pointing to your external web service you need to consume
Try using Mule DataMapper. That helps you to convert a JSON to XML in the more easier way. You can try it in Anypoint Studio of Mule.
I need to create a ReST service using Jersey 2.0. I need to send multiple documents and metadata to the client.
What is the best approach do to the achieve this.
I was able to send a MultiPart response from the server , but not sure how to read this from the client code
Let's say you have a document called "document1" which you want to get via your client.
In your REST-API your unique identifier for the document (the resource) could be:
http://example.com/restapi/documents/document1
As you want to READ data you do a HTTP-GET Request to that uri.
And here comes the important part for you: A resource can have multiple representations - meta data and binary data in your case.
So the client has to tell the server which representation type to get (content negotiation). This information can be set in the ACCEPT Header of the client request for instance.
You can use the content type "application/json" as a representation for the meta data.
Unfortunately you didn't tell us what kind of binary data you want to send.
If they are PDFs the content type would be "application/pdf" for instance. If the binary data doesn't have a specific type you can use "application/octet-stream".
Of course there is work to be done on the server side too. Here an example:
#Path("/documents/{documentname}")
public class docResource {
#GET #Produces("application/json")
public Response getDocumentMetaData(#PathParam("documentname") String docName) {
// Create a Response containing a json
}
#GET #Produces("application/pdf")
public Response getDocumentBinaryData(#PathParam("documentname") String docName) {
// Create a response containing the binary data
}
...
}
Jersey will check the accept header of the client and will run the appropriate method.
Also see: https://jersey.java.net/documentation/latest/jaxrs-resources.html
If you are using jersey with jackson you can also easily marshal a POJO to JSON and visa versa:
http://examples.javacodegeeks.com/enterprise-java/rest/jersey/json-example-with-jersey-jackson/
If you are not sure what to do in the "getDocumentBinaryData"-Method - checkout this simple example from mkyong:
http://www.mkyong.com/webservices/jax-rs/download-excel-file-from-jax-rs/
I am using Mule ESB version 1.3 and as soap engine it has AXIS1.4 embedded.Mule uses the code below to send stream as ws attachment. I checked they are still using it in newer versions.
File temp = File.createTempFile("soap", ".tmp");
temp.deleteOnExit(); // TODO cleanup files earlier (IOUtils
// has a file tracker)
FileOutputStream fos = new FileOutputStream(temp);
msgContext.getRequestMessage().writeTo(fos);
fos.close();
contentLength = (int)temp.length();
payload = new FileInputStream(temp);
Here the content of soap message with attachment is saved on a file and handle for this file is given to the rest of system. I did not get the logic behind this. Why not just use
javax.activation.DataHandler
inputstream and instead first saving and then reading message from file. As far as I understand Axis1.4 itself not working that way. Am I missing something here ?
After some modifications to make mule send file I came accross the below difference between axis and mule client generated messages. Except this line generated messages are same.
Mule generate this header:
Content-Type: multipart/related;type="application/xop+xml"
Axis generate this header which is correct:
Content-Type: multipart/related;type="application/xop+xml"; start="<2F4952A019F62AB6704A0C06DB5E8AA1>"; start-info="text/xml; charset=utf-8"; .boundary="----=_Part_0_1836994030.1387284330292"
What is causing this difference ?