2011-11-07 17 views
7

Tengo la tarea de crear un servicio WCF que será consumido por un cliente externo. El cliente está usando seguridad WSSE, específicamente, están pasando un token de nombre de usuario a través de un encabezado SOAP.Cliente WCF que pasa token de nombre de usuario con mustUnderstand establecido en true

El servicio WCF está alojado en un servidor IIS con SSL habilitado.

En este punto, tengo un prototipo semi-funcional. El problema que estoy tratando ahora es que el encabezado SOAP tiene el atributo mustUnderstand establecido en 1, y esto hace que el proceso falle.

Me gustaría obtener algunos consejos (o mejor aún, un ejemplo de código sonrisas) sobre cómo manejar el token de nombre de usuario de forma tal que se devuelva la respuesta correcta cuando el atributo mustUnderstand es verdadero.

He aquí una muestra de la solicitud SOAP que está fallando:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
     <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> 
       <wsse:Username>TestUser</wsse:Username> 
       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPWD</wsse:Password> 
       <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">NzU3MjFhN2YtYTlmYS00ZWZjLTkxNjktY2ExZjlkZDEwNzE5</wsse:Nonce> 
       <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-10-26T03:04:39Z</wsu:Created> 
      </wsse:UsernameToken> 
      </wsse:Security> 
     </soapenv:Header> 
     <soapenv:Body> 
      <tem:Getstuff> 
      <tem:Arg1>Arg1</tem:Arg1> 
      <tem:Arg2>Arg2</tem:Arg2> 
      </tem:Getstuff> 
     </soapenv:Body> 
    </soapenv:Envelope> 

Si soapenv: mustUnderstand = "1" pasa a soapenv: mustUnderstand = "0", entonces funciona el proceso.


PS: He aquí una muestra de revisado el cliente envía:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
     <s:Header> 
     <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/WService/Getstuff</Action> 
     <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="removed" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:Username>TestUser</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPass</wsse:Password> 
      <wsse:Nonce>2Udx78sh2y2xRJYJpZZ9+w==</wsse:Nonce> 
      <wsu:Created>2011-09-26T19:12:48Z</wsu:Created> 
      </wsse:UsernameToken> 
     </Security> 
     </s:Header> 
     <s:Body> 
     <Getstuff xmlns="http://tempuri.org/"> 
     <Arg1>Arg1</Arg1> 
     <Arg2>Arg2</Arg2> 
     </Getstuff> 
     </s:Body> 
    </s:Envelope> 

recibo la siguiente respuesta a las solicitudes anteriores:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
     <s:Body> 
      <s:Fault> 
      <faultcode>s:MustUnderstand</faultcode> 
      <faultstring xml:lang="en-US">The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.</faultstring> 
      </s:Fault> 
     </s:Body> 
    </s:Envelope> 

Aquí está el enlace:

<bindings> 
    <basicHttpBinding> 
    <binding name="TransportBind" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
     maxReceivedMessageSize="2147483647"> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     <security mode="Transport"> 
     <transport clientCredentialType="None" /> 
     </security> 
    </binding> 
    <binding name="basic" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
     maxReceivedMessageSize="2147483647"> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
+0

¿Está seguro de que está utilizando WSE (Web Service Extensions)? –

+0

No, no soy positivo. He agregado a la muestra anterior una solicitud de muestra revisada enviada por el cliente. –

+0

Exactamente lo que es el "error". Exactamente, ¿qué te hizo creer que la falla fue causada por 'mustUnderstand'? –

Respuesta

0

+1 @JohnSaunder s porque lo más probable es que esté ladrando el árbol correcto aquí.

¿Es su cliente .NET/WCF? De lo contrario, es posible que no implemente WS-Security, o al menos no de la manera en que WCF lo desea.

Si el cliente es .NET, esto es solo un enlace no coincidente en el lado del cliente.

El indicador mustUnderstand indica que el encabezado WS-Security debe reconocerse y procesarse. Un cliente que no sea WS-Security, ya sea porque no habla WS-Security o no está configurado para hacerlo, ignorará el encabezado, intentará utilizar el mensaje de todos modos y el servidor responderá puntualmente.

Su otra opción es rechazar el repudio en el servidor. Dejará de enviar encabezados de WS-Security. Por supuesto, entonces no obtienes el repudio.

+0

Estoy bastante seguro de que es un cliente de Java, pero no sé qué sabor. –

2

Su encuadernación es basicHttpBinding. Necesita usar wsHttpBinding.

0

Resolvió este problema al no usar el encabezado WS-Security generado (cuando agrega la Referencia del servicio) en la configuración WCF, sino que lo comenta y en su lugar permite que .NET genere el encabezado usando Credenciales de cliente y especificando un modo de seguridad de "TransportWithMessageCredential":

client.ClientCredentials.UserName.UserName = "UserName"; 
client.ClientCredentials.UserName.Password = "Password"; 

<basicHttpBinding> 
    <binding name="Binding"> 
     <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 
</basicHttpBinding> 

(Estamos utilizando SSL, por lo tanto, esta configuración de seguridad).

Comentadas de salida de cabecera generado:

<client> 
     <endpoint ...> 
      <!--<headers> 
       <wsse:Security...> 
       </wsse:Security> 
      </headers>--> 
     </endpoint> 
</client> 

Por desgracia, no sabemos lo suficiente WCF para capturar el jabón crudo petición/respuesta para comparar la diferencia y ver por qué ClientCredentials no hace que la "no se entendía "falla, mientras que el encabezado generado lo hace.

Como documentación aparte, according to the MSDN, si solo usa "Transporte" no sabrá usar WS-Security: "Deje esta propiedad en su valor predeterminado, que es System.ServiceModel.SecurityMode.Transport para no usar WS-Security ".

Cuestiones relacionadas