SOAPFaultException “MustUnderstand headers (oasis-200401-wss-wssecurity-secext-1.0.xsd) are not understood”

前端 未结 4 925
我寻月下人不归
我寻月下人不归 2020-12-14 18:32

I try to get information from web service that uses PasswordText WSS type. Firstly, I test it using soapUI and successfully got data. Then I implemented authentication on Ja

相关标签:
4条回答
  • 2020-12-14 19:09

    Here is what worked for me. Basically, it's an application of the idea pronounced by @Joseph Rajeev Motha (although I found it elsewhere, here: https://dwuysan.wordpress.com/2012/04/02/jax-ws-wsimport-and-the-error-mustunderstand-headers-not-understood/#comment-215 ), but his answer does not provide boilerplate, and without it, the answer is pretty mysterious.

    Please note that this sequence applies to the standalone case (where you publish an Endpoint yourself).

    Step 1

    Create a SOAPHandler that will 'understand' the header:

    public class WSSESecurityUnderstandPretender implements SOAPHandler<SOAPMessageContext> {
        @Override
        public Set<QName> 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 Set<QName> headers = new HashSet<>();
            headers.add(securityHeader);
    
            // notify the runtime that this is handled
            return headers;
        }
    
        @Override
        public boolean handleMessage(SOAPMessageContext context) {
            // we must return true, or else the runtime will return
            // wrong wrapper element name (like makeTransfer instead of
            // makeTransferResponse)
            return true;
        }
    
        @Override
        public boolean handleFault(SOAPMessageContext context) {
            // we must return true, or else the runtime will return
            // wrong wrapper element name (like makeTransfer instead of
            // makeTransferResponse)
            return true;
        }
    
        @Override
        public void close(MessageContext context) {
        }
    }
    

    Step 2

    Create a handler-chain.xml file and put it on classpath:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <javaee:handler-chains
         xmlns:javaee="http://java.sun.com/xml/ns/javaee"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <javaee:handler-chain>
        <javaee:handler>
          <javaee:handler-class>com.mypackage.WSSESecurityUnderstandPretender</javaee:handler-class>
        </javaee:handler>
      </javaee:handler-chain>
    </javaee:handler-chains>
    

    Step 3

    Annotate your implementation class (class that is annotated with @WebService) with a reference to the handler chain file:

    @HandlerChain(file = "handler-chain.xml")
    

    Step 4

    Publish your endpoint:

    Endpoint endpoint = Endpoint.publish(url, impl);
    

    An important note

    handleMessage() and handleFault() defined by the handler must return true. Otherwise, you will get strange errors like 'Unexpected wrapper element' because a different wrapper element name will be used.

    0 讨论(0)
  • 2020-12-14 19:16

    I found the solution. Following dependencies were required:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>2.2.3</version>
    </dependency>
    

    Good article on this topic and some pitfalls of cxf: http://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven/

    0 讨论(0)
  • 2020-12-14 19:17

    You could get this error when the service does not handle the headers. The service needs to implement a SOAPHandler with a getHeaders() that would resolve the headers. For the above mentioned fault the correct implementation would be as follows

     @Override 
        public Set<QName> getHeaders() { 
            QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
                    "Security"); 
            HashSet<QName> headers = new HashSet<QName>(); 
            headers.add(securityHeader);         
            return headers; 
        }
    

    It is also possible to get this when the service is actually not secure, but the client is attempting to use security configuration (possibly using a XWSS security configuration) For this, just check the published wsdl from a browser and make sure it contains the expected security policy (append ?wsdl to its endpoint URL)

    0 讨论(0)
  • 2020-12-14 19:17

    If you have this problem in project with Java 11 try to use Apache CXF 3.3.x release.
    Answer below from Apache CXF FAQ:

    Can CXF run with JDK/ Java 9+ (10, 11)?
    Yes. CXF will support Java 9-11 with the next 3.3.x release.

    0 讨论(0)
提交回复
热议问题