1
votes

Please help me in resolving this issue.

I'm writing a java SOAP client to hit a SOAP service of some third party that is working on HTPPS & accepts web-security in header. The soap service called-operation in turn returns a class object. I have written a class, while invoking the service, I'm getting below exception. I tried to get SOAP Envelop that is sent to the service & executed it with SOAP UI tool & got successful response. I'm a bit confused whats wrong as in , when I send SOAP envelop with my JAVA SOAP Client I get below exception while running same SOAP envelop with SOAP UI tool , I get successful response.

Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}MustUnderstand
faultSubcode: faultString: Did not understand "MustUnderstand" header(s):
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:96)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:1910)
at fibonacci.testing.TestService.main(TestService.java:92)

{http://xml.apache.org/axis/}hostname:localhost

Did not understand "MustUnderstand" header(s):
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:96)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:1910)
at fibonacci.testing.TestService.main(TestService.java:92)

2

2 Answers

0
votes

You probably have checked the below link discussing the mustUnderstand error specifically in the context of Axis http://wso2.org/library/tutorials/understand-famous-did-not-understand-mustunderstand-header-s-error

Have you confirmed the entire SOAP envelope from your code and the one used by SOAP is the same? is mustUnderstand set to 1 in both the cases?

0
votes

i faced this problem and i have solved it in my job... this type of message is set when there is no handler for security on you server.xsdd

in my case the xsdd implementation was built on axis 1.4, using java.rmi and javax.xml.rpc.Service

if that is your case, you will have 2 xsdd one for the server (ns declaration of your service) and a deploy.xsdd for other settings of your call.

first i add to my ns:operation this references to oasis security, after that i added to my service a requestflow

it should be something like this

<ns1:service name="YOUR SERVICE">  <!-- wss_username_token_over_ssl -->   <requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
  <parameter name="passwordCallbackClass" value=" YOUR PASSWORD HANDLER JAVA PATH LOCATION"/>
  <parameter name="action" value="UsernameToken"/>
</handler>   </requestFlow>  
 <ns1:operation name="YOUR OPERATION NAME" 
 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"
 .... other declarations ... />

depending of your security levels to create, in your passwordCallbackClassHandler, you must/or not validate the user and the password the handler should be something like this

public class PWCallback implements CallbackHandler {

  private static final byte[] key = {
    (byte)0x31, (byte)0xfd, (byte)0xcb, (byte)0xda,
    (byte)0xfb, (byte)0xcd, (byte)0x6b, (byte)0xa8,
    (byte)0xe6, (byte)0x19, (byte)0xa7, (byte)0xbf,
    (byte)0x51, (byte)0xf7, (byte)0xc7, (byte)0x3e,
    (byte)0x80, (byte)0xae, (byte)0x98, (byte)0x51,
    (byte)0xc8, (byte)0x51, (byte)0x34, (byte)0x04,
  };

public void handle(Callback[] callbacks)
        throws IOException, UnsupportedCallbackException {
    System.out.println("DENTROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
        for (int i = 0; i < callbacks.length; i++) {
          if (callbacks[i] instanceof WSPasswordCallback) {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
            /*
             * here call a function/method to lookup the password for
             * the given identifier (e.g. a user name or keystore alias)
             * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
             * for testing we supply a fixed name/fixed key here.
             */
            if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {
              pc.setKey(key);
            }
            else {
              pc.setPassword("security");
            }
          } else {
            throw new UnsupportedCallbackException(
              callbacks[i], "Unrecognized Callback");
          }
        }
      }

}

hope this helps you regards