WS-Security mustUnderstand
Environment: webmethods 8.0.1
Problem
A client has asked us to enable ws-security when using a particular webservice he exposes (webmethods policy "Consumer policy for Username"). However when we call his webservice with the appropriate message level authentication, we receive the following soap fault:
Analyzing the problem
Using wireshark/fiddler/.. you can inspect the soap that webmethods sends along and you see this:
As you can see, the "mustUnderstand" header is indeed set. Transmitting the entire soap sans mustUnderstand via soapUI works. A quick google showed us that we are not the only ones experiencing this but no solutions were forthcoming. A succinct explanation of mustUnderstand can be found here.
The most likely cause of the issue is a bug in the client webservice implementation where he does interpret the security header but does not clear the mustUnderstand attribute which would result in the error we are seeing.
Solution
The simplest solution is of course for us not to send along the attribute but unfortunately we found no reference in the documentation regarding this particular functionality. Instead we opted to write a custom soap handler which strips the attribute when found. The webservice functionality has been subjected to a large overhaul in 8.0.1 so instead of extending javax.xml.rpc.handler.GenericHandler to add some functionality, you can work with actual services. This makes it much easier to test changes on the fly.
We create a handler service that implements the spec pub.soap.handler:handlerSpec:
The java service DgCommon.admin.utils:removeMustUnderstand uses the public org.w3c.dom api to strip the mustUnderstand:
This will however not work and give you a rather vague error:
The exception is not entirely according to the spec so I assume this is an error in the webmethods implementation. Anyway, removing it with a fully qualified namespace does work:
You can register the handler using pub.soap.handler:registerWmConsumer (note that this must be re-registered on reboot, so do it in a startup service).
The last step is to actually add it to your list of handlers:
Author: Alexander Verbruggen
Did I do this correctly? I am getting the Bundle:com.wm.dom.resources.DOMMessageBundle Key:133.8 error.
ReplyDeleteIDataCursor cursor = pipeline.getCursor();
org.w3c.dom.Element element = (org.w3c.dom.Element) IDataUtil.get(cursor, "header");
element.removeAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "mustUnderstand");
IDataUtil.put(cursor, "header", element);
cursor.destroy();
The code looks good. For simplicity's sake, the code does not take into account additional headers that do not have a mustUnderstand, it is possible that if you try to call removeAttributeNS() on an element that does not have the attribute to begin with, it could result in an exception.
ReplyDeleteI have not tested this and it is against the specifications so I can't be sure. You could check if the header has the required attribute before attempting to remove it.