SoapFaultException "Los encabezados de MustitEdtand (OASIS-200401-WSS-WSSECURITY-SECEXT-1.0.XSD) no se entienden"

StackOverflow https://stackoverflow.com/questions/9364428

  •  28-10-2019
  •  | 
  •  

Pregunta

Intento obtener información del servicio web que use el tipo de contraseña WSS. En primer lugar, lo pruebo con Saampui y obtuve con éxito datos. Luego implementé autenticación en Java, escribiendo SecurityHandler:

public final class SecurityHandler implements SOAPHandler<SOAPMessageContext> {

...

@Override
public boolean handleMessage(SOAPMessageContext messageContext) {
    boolean outInd = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if (outInd) {
        try {
            WSSecUsernameToken builder = new WSSecUsernameToken();
            builder.setPasswordType(WSConstants.PASSWORD_TEXT);
            builder.setUserInfo(_username, _password);
            builder.addNonce();
            builder.addCreated();

            Document doc = messageContext.getMessage().getSOAPPart().getEnvelope().getOwnerDocument();
            WSSecHeader secHeader = new WSSecHeader();
            secHeader.insertSecurityHeader(doc);
            builder.build(doc, secHeader);
        } catch (Exception e) {
            LOGGER.error("Unable to handle SOAP message", e);
            return false;
        }
    }
    return true;
}

...
}

Revisé el objeto DOC con XMLUtils.PrettyDocumentToString(doc) y Saw, que se ve le gusta el XML enviado por Soupui: toda la información de autenticación (inicio de sesión, contraseña, nonce y tiempo creado) estaban en lugar, Debe entender atributo de Security La etiqueta era verdad.

Entonces me enfrenté a un error:

javax.xml.ws.soap.soapfaultException: Mustoderstand Headers: [{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd} Seguridad] no se entienden

Encontré consejos para eliminar el atributo de MustOdstand de Security Etiqueta, pero no ayuda. ¿Tienes alguna idea?

PD

El punto final del servicio web está en Https.

Parte de la política de WSDL:

<wsp:Policy wsu:Id="BasicHttpBinding_RelateService_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:TransportBinding>
                <wsp:Policy>
                    <sp:TransportToken>
                        <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                        </wsp:Policy>
                    </sp:TransportToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256/>
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Lax/>
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:IncludeTimestamp/>
                </wsp:Policy>
            </sp:TransportBinding>
            <sp:SignedSupportingTokens>
                <wsp:Policy>
                    <sp:UsernameToken
                            sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp:WssUsernameToken10/>
                        </wsp:Policy>
                    </sp:UsernameToken>
                </wsp:Policy>
            </sp:SignedSupportingTokens>
            <sp:Wss10>
                <wsp:Policy/>
            </sp:Wss10>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

Solicitud de jabón:

<soapenv:Envelope xmlns:ns="http://api.example.com/RelateService/1.0"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1"
                       xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-37"
                                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <wsse:Username>username</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
                    password
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    li/0YK2wxrmrHL7Cg+etdQ==
                </wsse:Nonce>
                <wsu:Created>2012-02-21T08:59:10.262Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <ns:RetrieveCustomerByEmail>
            <ns:email>xxx@example.com</ns:email>
            <ns:firstName/>
            <ns:lastName/>
        </ns:RetrieveCustomerByEmail>
    </soapenv:Body>
</soapenv:Envelope>

Mi petición:

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <wsse:Security 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"
                       S:mustUnderstand="1">
            <wsse:UsernameToken wsu:Id="UsernameToken-1">
                <wsse:Username>username</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
                    password
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    +jeleKO9zr0/wLjAIYcmSg==
                </wsse:Nonce>
                <wsu:Created>2012-02-21T09:42:03.760Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </S:Header>
    <S:Body>
        <ns5:RetrieveCustomerByEmail xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
                                     xmlns:ns2="http://schemas.datacontract.org/2004/07/XXX.Service"
                                     xmlns:ns3="http://schemas.datacontract.org/2004/07/XXX.Service.Relate.Contract"
                                     xmlns:ns4="http://schemas.datacontract.org/2004/07/XXX.Service.Dto"
                                     xmlns:ns5="http://api.example.com/RelateService/1.0"
                                     xmlns:ns6="http://schemas.microsoft.com/2003/10/Serialization/">
            <ns5:email>xxx@example.com</ns5:email>
            <ns5:firstName/>
            <ns5:lastName/>
        </ns5:RetrieveCustomerByEmail>
    </S:Body>
</S:Envelope>
¿Fue útil?

Solución 2

Encontré la solución. Se requerían las siguientes dependencias:

<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>

Buen artículo sobre este tema y algunas trampas de CXF: http://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven/

Otros consejos

Puede obtener este error cuando el servicio no maneja los encabezados. El servicio necesita implementar un Soaphandler con un Getheaders () que resolvería los encabezados. Para la falla mencionada anteriormente, la implementación correcta sería la siguiente

 @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; 
    }

También es posible obtener esto cuando el servicio en realidad no es seguro, pero el cliente intenta usar la configuración de seguridad (posiblemente usando una configuración de seguridad XWSS) para esto, simplemente verifique el WSDL publicado desde un navegador y asegúrese de que contenga la esperada. Política de seguridad (append? WSDL a su URL de punto final)

Esto es lo que funcionó para mí. Básicamente, es una aplicación de la idea pronunciada por @Joseph Rajeev Motha (aunque la encontré en otro lugar, aquí: https://dwuysan.wordpress.com/2012/04/02/jax-ws-wsimport-and-the-error-musterstand-headers-not-oderstood/#comment-215 ), pero su respuesta no proporciona Boilerplate, y sin ella, la respuesta es bastante misteriosa.

Tenga en cuenta que esta secuencia se aplica al caso independiente (donde publica un Endpoint tú mismo).

Paso 1

Crear un SOAPHandler que 'comprenderá' el encabezado:

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) {
    }
}

Paso 2

Crear un handler-chain.xml archivo y ponerlo en 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>

Paso 3

Anotar su clase de implementación (clase que se anota con @WebService) con una referencia al archivo de la cadena del controlador:

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

Paso 4

Publique su punto final:

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

Una nota importante

handleMessage() y handleFault() definido por el controlador debe regresar true. De lo contrario, obtendrá errores extraños como 'elemento de envoltura inesperado' porque se utilizará un nombre de elemento de envoltura diferente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top