Reputation: 51
This is my first post here so please be patient. I have a WSDL and I used SOAP UI to generate the Java Client. I plugged in the client into a test project and am using the client to access the web service. The web service expects security headers(which are not a part of the wsdl policy) so I had to use Handlers in order to add Security Headers to the SOAP Envelope which is created. On running my program it throws the following error... When I run the same SOAP request via SOAP UI it seems to process fine. Another interesting thing I noticed is that although I run the same request(including nonce of the security header) in SOAP UI after processing it in my client (after the error is thrown) it still seems to process fine. But when I try and run the same request in the SOAP UI twice it throws an exception which is along the lines of not being able to use the same Nonce value more than once (This is expected behavior). This makes me think that the error that is being generated after running my client is not even reaching the server running the web service otherwise the nonce would have been cached there and I wouldn't be able to run it in SOAP UI. I have attached my Handler class method below the Error block. I am inclined to believe that the security header is fine since the message processes fine in SOAP UI. Any help is appreciated.
javax.xml.ws.soap.SOAPFaultException: MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood at com.sun.xml.internal.ws.protocol.soap.MUTube.createMUSOAPFaultException(Unknown Source) at com.sun.xml.internal.ws.protocol.soap.ClientMUTube.processResponse(Unknown Source) at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source) at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source) at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source) at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source) at com.sun.xml.internal.ws.client.Stub.process(Unknown Source) at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(Unknown Source) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source) at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(Unknown Source) at com.sun.proxy.$Proxy34.searchDemographics(Unknown Source) at com.douglas.client.Client.main(Client.java:50)
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
SOAPMessage message = smc.getMessage();
try {
//message.writeTo(System.out);
//System.out.println("\n");
String nonce = getNonce();
String password1 = "password01";
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String messageCrTime = ft.format(new Date());
String passwordDigest = SHAsum(nonce, password1, messageCrTime);
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security =
header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username =
usernameToken.addChildElement("Username", "wsse");
username.addTextNode("USERNAME");
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
password.addTextNode(passwordDigest);
SOAPElement nonceElem =
usernameToken.addChildElement("Nonce", "wsse");
//password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
nonceElem.addTextNode(Base64.encodeBytes(nonce.getBytes()));
SOAPElement created =
usernameToken.addChildElement("Created", "wsu");
//password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
created.addTextNode(messageCrTime);
//Print out the outbound SOAP message to System.out
message.writeTo(System.out);
System.out.println("");
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
//This handler does nothing with the response from the Web Service so
//we just print out the SOAP message.
SOAPMessage message = smc.getMessage();
message.writeTo(System.out);
System.out.println("");
} catch (Exception ex) {
ex.printStackTrace();
}
}
return outboundProperty;
}
Upvotes: 2
Views: 2589
Reputation: 51
Found out the solution. The reason the client is throwing these errors is because when it receives the response back from the web service the mustUnderstand is set to '1'. Now since the WSDL policy did not include the security components, the client does not know what to do with it. The work around is to add the following method in your HeaderHandler.java class.
public Set getHeaders() {
final QName securityHeader = new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse");
final HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
//throw new UnsupportedOperationException("Not supported yet.");
}
Upvotes: 1