jueves, 4 de julio de 2019

Error visual studio c# - consumiento SOAP: El destinatario de este mensaje no entendió el encabezado 'Security' del espacio de nombres

¿Cómo solucionar el error del encabezado 'Security'?

El otro día me toque con este error, me pase un buen rato investigando el por qué, pero luego de entenderlo, les traigo la explicación básica por este medio, porque el conocimiento se comparte.

Mensaje de error: 

'El destinatario de este mensaje no entendió el encabezado 'Security' del espacio de nombres 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', por lo que el mensaje no se procesó. Este error suele indicar que el remitente del mensaje habilitó un protocolo de comunicación que el destinatario no puede procesar. Asegúrese de que la configuración del enlace del cliente es coherente con el enlace del servicio.'


Recordemos que significa SOAP y cuales son sus componentes:

SOAP (originalmente las siglas de Simple Object Access Protocol) es un protocolo estándar que define cómo dos objetos en diferentes procesos pueden comunicarse por medio de intercambio de datos XML fuente Wikipedia.

Componentes del mensaje:

Sobre (envelope) : El cual encapsula todo el contenido del mensaje.
Cabecera (header): Contiene información de cabecera como las credenciales de nuestro problema.
Cuerpo (Body): Contiene e cuerpo del mensaje.
Falla (Fault): Contiene información relacionada a errores que se puedan producir al consumir el servicio.

El error indica que el destinatario no entendió el encabezado 'Security', pues si vemos la respuesta de servicio web:

<s:Header>
  <o:Security s:mustUnderstand="1" 
     xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
              wss-wssecurity-secext-1.0.xsd">
     <u:Timestamp u:Id="_0">
        <u:Created>2019-07-01T23:40:19.933Z</u:Created>
        <u:Expires>2019-07-01T23:45:19.933Z</u:Expires>
     </u:Timestamp>
  </o:Security>
</s:Header>

Encabezado Header Security



Nuestro caso a investigar nos indica error en el espacio de nombres, así que veamos que significa:

Los URI de espacio de nombres (de la forma general "some-URI") representan algunos URI dependientes de la aplicación o dependientes del contexto, como se define en RFC 3986 [URI] . Esta especificación está diseñada para funcionar con la estructura general de mensajes SOAP [ SOAP11 , SOAP12 ] y el modelo de procesamiento de mensajes, y debe ser aplicable a cualquier versión de SOAP. El URI del espacio de nombres SOAP 1.1 actual se usa en este documento para proporcionar ejemplos detallados, pero no hay intención de limitar la aplicabilidad de esta especificación a una versión única de SOAP. Fuente: Oasis-Open
Aquí podrán encontrar mayor detalle:
https://www.oasis-open.org/committees/download.php/13392/wss-v1.1-spec-pr-UsernameTokenProfile-01.htm

Nos muestra la siguiente tabla:

Prefijo
   Espacio de nombres
S11
S12
wsse
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
wsse11
http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd
wsu
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd


Veamos qué es WSSE (Web Service Security Especification):
WSSE es una especificación de seguridad de SOAP, y protege el consumo de los servicios web SOAP contra los ataques de intermediarios, la seguridad a nivel de transporte se puede utilizar para proporcionar confidencialidad e integridad.

Forma de consumo:

Instanciar tu cliente - C#:
ServiceABC.ServicioABCPortTypeClient Cliente = new ServiceABC.ServicioABCPortTypeClient();
Cliente.ClientCredentials.Username = "ABC_Usuario";
Cliente.ClientCredentials.PAssword = "XXXXXXXXXXX";
Cliente.ClientCredentials.UseIdentityConfiguration = true;
//Luego Consumir tu servicio, lo anterior puede cambiar de acuerdo al servicio a consumir
var response = Cliente.GetData("DatoSolicitado");

Configurar tu Web.Config

De:
<binding name="SevicioABCSoap11Binding">
          <security mode="Transport" />        
</binding>

A:
<binding name="SevicioABCSoap11Binding">
          <security mode="TransportWithMessageCredential" />        
</binding>

Con ésto se solucionará, ya que el cliente en la  configuración <security mode="Transport" /> no espera el tag <security>, en cambio con <security mode="TransportWithMessageCredential" />  nuestro cliente ya espera el header. (Los datos expuestos en este post son de ejemplo)

Saludos, deseo que les haya sido de utilidad, espero sus comentarios y/o recomendaciones

3 comentarios: