removing mustUnderstand attribute from soap headers

回眸只為那壹抹淺笑 提交于 2019-12-04 11:06:27
Reinhard

If you want to disable the must understand check in the AXIS client you have to add the following line to your code:

_call.setProperty(Call.CHECK_MUST_UNDERSTAND, new Boolean(false));

then the MustUnderstandChecker of the AXIS Client is never invoked.

Javarome

None of those solutions worked for me, as:

Looking at the answer to "Adding ws-security to wsdl2java generated classes" helped me to write a solution that worked for me:

void addSecurityHeader(Stub stub, final String username, final String password) {
  QName headerName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");  // Or any other namespace that fits in your case
  AtomicReference<SOAPHeaderElement> header 
    = new AtomicReference<SOAPHeaderElement>
        (new SOAPHeaderElement(headerName) {                       
           {  
             SOAPElement utElem = addChildElement("UsernameToken");
             utElem.addChildElement("Username").setValue(username);
             utElem.addChildElement("Password").setValue(password);
           }
           @Override
           public void setAttribute(String namespace, String localName, String value) {
             if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) {  // Or any other attribute name you'd want to avoid
               super.setAttribute(namespace, localName, value);
             }
           }
        });
  SOAPHeaderElement soapHeaderElement = header.get();
  soapHeaderElement.setActor(null);      // No intermediate actors are involved.
  stub.setHeader(soapHeaderElement);  // Finally, attach the header to the stub
}
Daniel Pawlik

In my case it worked manually remove the attribute from the SOAPHeader

SOAPHeader header = env.getHeader();
OMChildrenQNameIterator childrenWithName = (OMChildrenQNameIterator) header.getChildrenWithName(omElementauthentication.getQName());
    while (childrenWithName.hasNext()) {
        org.apache.axiom.om.OMElement omElement = (org.apache.axiom.om.OMElement) childrenWithName.next();
        QName mustAnderstandQName = omElement.resolveQName("soapenv:mustUnderstand");
        if (mustAnderstandQName == null) {
            continue;
        }
        OMAttribute mustAnderstandAttribute = omElement.getAttribute(mustAnderstandQName);
            if (mustAnderstandAttribute == null) {
                continue;
            }
        omElement.removeAttribute(mustAnderstandAttribute);
    }

I was recently struggling with similar situation and by doing some google-ing I managed to find the following solution.

Having used Axis2 you would've probably generated a MyWSStub file that contains the calls to your service. Create an wrapper class (better not touch the auto-generated stub files) that extends your stub e.g. MyWSStubWrapper:

public class MyWSStubWrapper extends MyWSStub {

/**
 * @throws AxisFault
 */
public MyWSStubWrapper() throws AxisFault {
}

/**
 * @param configurationContext
 * @throws AxisFault
 */
public MyWSStubWrapper(ConfigurationContext configurationContext) throws AxisFault {
    super(configurationContext);
}

/**
 * @param targetEndpoint
 * @throws AxisFault
 */
public MyWSStubWrapper(String targetEndpoint) throws AxisFault {
    super(targetEndpoint);
}

/**
 * @param configurationContext
 * @param targetEndpoint
 * @throws AxisFault
 */
public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint) throws AxisFault {
    super(configurationContext, targetEndpoint);
}

/**
 * @param configurationContext
 * @param targetEndpoint
 * @param useSeparateListener
 * @throws AxisFault
 */
public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint, boolean useSeparateListener) throws AxisFault {
    super(configurationContext, targetEndpoint, useSeparateListener);
}

@Override
protected void addHeader(OMElement omElementToadd, SOAPEnvelope envelop, boolean mustUnderstand) {
    SOAPHeaderBlock soapHeaderBlock = envelop.getHeader().addHeaderBlock(omElementToadd.getLocalName(), omElementToadd.getNamespace());
    OMNode omNode = null;

    // add child elements
    for (Iterator iter = omElementToadd.getChildren(); iter.hasNext();) {
        omNode = (OMNode) iter.next();
        iter.remove();
        soapHeaderBlock.addChild(omNode);
    }

    OMAttribute omatribute = null;
    // add attributes
    for (Iterator iter = omElementToadd.getAllAttributes(); iter.hasNext();) {
        omatribute = (OMAttribute) iter.next();
        soapHeaderBlock.addAttribute(omatribute);
    }
}

}

Bear in mind that the above code will completely remove the soapenv:mustUnderstand="0|1" from your headers if you wish to added you need to call soapHeaderBlock.setMustUnderstand(true|false); somewhere in your code.

1) Are you using the Axis SOAPHeaderElement and if so, are you setting the mustUnderstand setter to false?

2) Since you're generating your client with wsdl2java, it's quite possible that the WSDL (or more accurately, the schema) contains the mustUnderstand attribute on an element referenced in your SOAP binding. So when wsdlToJava generates the client code, those attributes will naturally be added. See here for a description of the mustUnderstand attribute. If modifying the WSDL is out of the question, and you must remove this attribute from the header, then I suppose you can try to do it with a handler

3) Not advisable, but if you really MUST remove this attribute then I suppose you can add a client side handler that alters the header: http://ws.apache.org/axis/java/apiDocs/org/apache/axis/handlers/package-summary.html

i am using axis 1.4 client with ws security

in my case as Reinhard said this worked

MyService service = new MyServiceLocator(); 
MyServicePortType port = service.getMyServiceHttpsSoap11Endpoint();

((Stub) port)._setProperty(Call.CHECK_MUST_UNDERSTAND, Boolean.FALSE);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!