Se me solicito realizar un implementación de WebServices para publicar los servicios de la Empresa para la cual estoy dando servicios.
Una vez terminado dicho proyecto, se procedió a realizar las pruebas necesarias de la implementación, para esto ser utilizo la herramienta SoapUI, sin encontrar inconvenientes en el consumo de estos (https + ws-security).
Bueno, todo estaba bien, hasta que se intento realizar un demo con .Net (VS2010).
Dejo una URL donde aparece una forma bastante “didáctica” de como consumir un WebService:
http://www.elguille.info/colabora/NET2005/sergio_CallWebService.htm
Una vez realizado dicha tarea, nos agrega la siguiente configuración al archivo app.config:
Seleccionamos el EndPoint que vamos a utilizar, en nuestro ejemplo:
El código utilizado para la llamada al WebService es el siguiente:
Cuando ejecutamos el programa ejemplo, nos encontramos con el primer problema grave, que es el reclamo que el certificado es “falso”:
El sistema de seguridad del framework .Net es bastante exigente en ese punto. Para poder continuar con nuestras pruebas, vamos a “enganchar” una función que realice esta funcionalidad y no el framework:
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);
Donde la función es la siguiente:
public static bool IgnoreCertificateErrorHandler(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
System.Console.WriteLine("Warning, trust any certificate");
return true;
}
Solo retornamos “true” para todas las validaciones y con esto podemos continuar con la invocación del
WebService:
Ahora si ejecutamos el programa, nos genera una excepción porque no cumplimos con los criterios de seguridad puestas en el WebService (WS-Security):
Para esto abrimos el archivo “app.config” de nuestro proyecto y le indicamos el nivel de seguridad necesario:
Lo cambiamos por:
Una vez hecho esto, ejecutamos nuestro programa obteniendo la siguiente respuesta:
Esto significa que el WebService nos esta exigiendo las credenciales necesarias impuesta en la configuración del WS-Security, para nuestro caso UserToken:
serviceProxy.ClientCredentials.UserName.UserName = "comercio1";
serviceProxy.ClientCredentials.UserName.Password = "comercio1";
Quedando nuestro programa de la siguiente forma:
Ahora con esto, nuestra aplicación no debiese tener ningún inconveniente para poder consumir el WebService. Ejecutamos:
Otro error más!!! Si analizamos el mensaje:
El procesador de seguridad no encontró un encabezado de seguridad en el mensaje. La causa puede ser que el mensaje sea un error no protegido o que no coincidan los enlaces entre las partes de la comunicación. Esto puede suceder si el servicio esta configurado para seguridad y el cliente no usa seguridad.
Bueno!, ahora nos encontramos con este problema, lo cual analizando nuestro
WebService, este si respondió al requerimiento, es decir, por el lado del servidor, todo esta funcionando correctamente; el mensaje fue recibido, fue procesado, y se obtuvo una respuesta exitosa al requerimiento. Pero algo no le gusto al “
Procesador de Seguridad” de .Net que nos “atrapa” la respuesta.
Después de mucho buscar y analizar el problema, se encontró con una solución bastante atípica. La cual consiste en eliminar del mensaje la cabecera
SOAP del requerimiento la fecha y hora (TimeStamp), para que de esta forma en la respuesta no viaja la cabecera
SOAP, y evita que el “
Procesador de Seguridad” haga la fallida comparación.
BindingElementCollection elements = serviceProxy.Endpoint.Binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().IncludeTimestamp = false;
serviceProxy.Endpoint.Binding = new CustomBinding(elements);
Quedando nuestro código de la siguiente forma:
Ahora ejecutamos nuestro programa:
Y Funciona!. Espero que sea de ayuda….
Marco!