I am developing a web service client.
Unprocessed 'mustUnderstand' header element: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security
Wherever it works fine with SoapUI, returns proper response with following header:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<S:Header>
<wsse:Security S:mustUnderstand="1">
<wsu:Timestamp wsu:Id="XWSSGID-13660988101781895308327" xmlns:ns15="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity" xmlns:ns14="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns13="http://www.w3.org/2003/05/soap-envelope">
<wsu:Created>2013-04-16T08:02:05Z</wsu:Created>
<wsu:Expires>2013-04-16T08:07:05Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</S:Header>
I can not use wsHttpBinding. My request is:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>wstest</wsse:Username>
<wsse:Password>wstest</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<env:Body>
<-- client method call implementation>
</env:Body>
</env:Envelope>
please help me on this.
in the getHeaders() method you would need to return a XML element that would contain the root element. In this case, I would build a QName element with the following instantiation and add to a Set and return that in the getHeaders element:
#Override
public Set<QName> getHeaders(){
Set<QName> headers = new HashSet<QName>();
QName ck = new QName("http://coldyak.com", "coldyak", "cyk");
headers.add(ck);
return headers;
}
This is all that's needed to handle the mustunderstand attribute. It's sort of like a contract that enforces the webservice to process the header element.
Related
I am trying to automate the xml web services using Apache Axis Java API and I have generated the stubs. But my Below XML has header part which i need to customize manually using stub.
So I have used SOAPHeaderElement from stub class and designed the code. But I am getting extra namespace like xmlns:wsse="" in each node and soapenv: in header node.
So, please modify my code to get the exact format(Expected) as given below
Below is the XML Header Part:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsse:Header mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>InternalServiceUser</wsse:Username>
<wsse:Password>123456</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</wsse:Header>
</soapenv:Header>
Below is the code:
SOAPHeaderElement wsseHeader = new SOAPHeaderElement(new PrefixedQName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Header", "wsse"));
String nullString = null;
MessageElement Security = new MessageElement(nullString, "wsse:Security");
MessageElement usernameToken = new MessageElement(nullString, "wsse:UsernameToken");
MessageElement username = new MessageElement(nullString, "wsse:Username");
MessageElement password = new MessageElement(nullString, "wsse:Password");
username.setObjectValue("InternalServiceUser");
usernameToken.addChild(username);
password.setObjectValue("123456");
usernameToken.addChild(password);
Security.addChild(usernameToken);
wsseHeader.addChild(Security);
wsseHeader.setActor(null);
wsseHeader.setMustUnderstand(true);
_call.addHeader(wsseHeader);
Expected Request XML Header part:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsse:Header mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Security mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>InternalServiceUser</wsse:Username>
<wsse:Password>123456</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</wsse:Header>
</soapenv:Header>
Actual request XML header part which is generated after execution:
could not remove soapenv: in header tag and xmlns:wsse="" in Security, Username and password tags via code
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsse:Header soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Security xmlns:wsse=""><wsse:UsernameToken xmlns:wsse="">
<wsse:Username xmlns:wsse="">InternalServiceUser</wsse:Username>
<wsse:Password xmlns:wsse="">123456</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</wsse:Header>
</soapenv:Header>
I'm trying to create a client to a ws (using wsimport) that requires a UsernameToken header with digest.
The header must be like this:
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-32E6B34377D7E4A58614607283662392">
<wsu:Created>xxxx</wsu:Created>
<wsu:Expires>xxxxx</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-32E6B34377D7E4A58614607283662221">
<wsse:Username>xxxx</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">xxxxx</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">xxxxxxx</wsse:Nonce>
<wsu:Created>xxxxxx</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
It seems to be a default soap header but I not found a easy way to generate it.
How can I add this header in my request?
Thank you.
I have written a WebService Client in Java (Spring) that produces the following SOAP Message
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken-636BB26257F688077A14836055821331">
<wsse:Username>
<!-- Removed-->
</wsse:Username>
<wsse:Password>
<!-- Removed-->
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<To SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://fi422helswb035/invoicewstest/ProblematicInvoiceWebService.svc/externalpartnerInvoiceWebService</To>
<Action SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://invoice.externalpartner.com/WebServices/IexternalpartnerInvoiceWebService/GetInvoices</Action>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns4:GetInvoices xmlns:ns2="http://schemas.datacontract.org/2004/07/externalpartner.Invoice.Web.Service.Interfaces.Types" xmlns:ns3="http://schemas.datacontract.org/2004/07/externalpartner.Invoice.Web.Service.Interfaces" xmlns:ns4="https://invoice.externalpartner.com/WebServices/" xmlns:ns5="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:ns6="http://schemas.datacontract.org/2004/07/externalpartner.Invoice.Web.Service.Exceptions">
<customerNumber xmlns="https://invoice.externalpartner.com/WebServices">10134</customerNumber>
</ns4:GetInvoices>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This message is Rejected on the server side with a 500 error. I can invoke the service with SOAP-UI; the following message (produced by SOAP UI is accepted)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="https://invoice.externalpartner.com/WebServices/">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-134751B2732DA1D93F148360576695534">
<wsse:Username>
<!-- Removed-->
</wsse:Username>
<wsse:Password>
<!-- Removed-->
</wsse:Password>
<wsse:Nonce>
<!-- Removed-->
</wsse:Nonce>
<wsu:Created>2017-01-05T08:42:46.955Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<To soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://fi422helswb035/invoicewstest/ProblematicInvoiceWebService.svc/externalpartnerInvoiceWebService</To>
<Action soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://invoice.externalpartner.com/WebServices/IexternalpartnerInvoiceWebService/GetInvoices</Action>
</soapenv:Header>
<soapenv:Body>
<web:GetInvoices>
<!-- Optional:-->
<web:customerNumber>10134</web:customerNumber>
</web:GetInvoices>
</soapenv:Body>
</soapenv:Envelope>
The real difference I can spot is the up front Name Space declaration in the accepted message. The web namespace is declared in the Envelope element - and in my rejected request it is declared in the element itself.
There are obviously also the missing a nonce and created elements, but according to the Oasis standards, those are not mandatory.
The question is; does the SOAP specification dictate where namespace declarations should be done? My best guess is that the rejected SOAP message is perfectly valid, and that there is a server side issue here...
I try to validate security header expiration using wss4j:
List<WSSecurityEngineResult> resultList = wsSecurityEngine.processSecurityHeader(doc,
"Actor", callbackHandler, crypto);
But wss4j doesn't see header content and result is null.
soap request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
soapenv:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-CC2DD79172C7EFA866147066307733352">
<wsu:Created>2016-08-08T13:31:17.333Z</wsu:Created>
<wsu:Expires>2016-08-09T13:31:17.333Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
It doesn't throw any exception. Just security header is ignored. In debug it can find all ChildNodes (soapenv:Header, wsse:Security etc.)
I have used Axis2 for the creation of stubs.
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>Uname</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pwd</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
can anyone give me the java soap client code for the above header
First link in Google for (adding soap header in axis2 example)
Working with Custom SOAP Headers