Design a site like this with WordPress.com
Get started

Consumiendo un servicio WCF desde un cliente C++ no manegado con paso de credenciales

Después de unos cuantos choques contra la pared lo he conseguido.  En este post explico lo que he hecho para que funcione y también he puesto unos cuantos recursos que he encontrado durante la investigación.

Servicio Paso 1: Bindings y Seguridad

Para maximizar la interoperativilidad de un servicio WCF, manteniendo el flujo de credenciales, el servicio WCF necesita ser configurado de una manera especial. Lo más crítico es la configuración adecuada de los bindings y de la seguridad; he tardado mucho tiempo en conseguir un basicHttpbinding con el modo seguro “TransportWithMessageCredentials”. Esta resultó ser la manera incorrecta de hacerlo (en nuestro caso). El modo de seguridad era en Transporte con las credenciales (clientCredentialType) de Windows.

<basicHttpBinding>
<binding name=”basic”>
 <security mode=”Transport”>
  <transport clientCredentialType=”Windows” />
 </security>
</binding>
</basicHttpBinding>
Básicamente estamos diciendo que la seguridad estará en la capa de transporte (SSL con http- https), con las credenciales de windows que se pasarán a nivel de transporte (cabeceras http – creo). El siguiente problema es hostear el servicio en IIS.

Servicio Paso 2. Configuración de IIS

Las credenciales en IIS deben corresponderse con la configuración del binding del servicio. En este caso, lo que quiere decir es que deshabilitemos el acceso anónimo y habilitemos la autenticación de windows. Fijáos que el servicio debe hostearse en un sitio SSL (en este post se explica cómo configurarlo). Intentad crear y ver el servicio.

Si véis un mensaje de error diciendo que el servicio necesita acceso anónimo significa que hay algún problema con vuestros bindings. En mi caso esto se debía a que tenía un endpoint mex para el servicio (ya que se genera automáticamente), pero como no usaba la mísma configuración del binding estaba dando problemas cuando le pedía acceso anónimo (en IIS). Es importante que todos los endpoints del servicio tengan opciones compatibles de seguridad.

Si veis un error diciendo que el servicio necesita autenticación de windows, eso es debido a un problema con IIS (En este blog está la solución – notad que en nuestro caso, debido a una configuración compleja d IIS, las instrucciones no estaban del todo bien, básicamente, aseguraos de que la seccion <IISWebService> que hace referencia a tu sitio, la línea NTAuthenticationProviders=”Negotiate,NTLM” está incluida).

Hasta este punto deberíais ser capaces de ver el servicio en vuestro navegador y ver el wsdl.

Servicio Paso 3 – Mejorando la interoperativilidad de WSDL

El comportamiento por defecto de WCF permite importar documentos wsdl y esquemas xsd (usando la sintaxis wsdl=wsdl0, xsd=xsd0). Algunas herramientas de generación de proxies no son capaces de manejar estas importaciones. Sin embargo para mejorar la interoperativilidad haced lo siguiente:

Usad WSDLExportExtension para incluir el XSD inline

Los comportamientos (behaviours) de WCF permiten sobreescribir la manera en que se generar los wsdl. Un behaviour personalizado puede eliminar todas las csd importadas y meterlas inline. Los detalles los tenéis en

http://www.winterdom.com/weblog/2006/10/03/InlineXSDInWSDLWithWCF.aspx

Que todas las wsdl aparezcan inline

También es posible usar un behaviour personalizado para importar inline todas las wsdl, sin embargo hasta donde he llegado, nadie ha creado esto. En el lado positivo tenemos que todos los tipos de contratos (datos, servicio, …) comparten el mismo namespace xml así que no se importan ningun wsdl.

Cliente Paso 1. Preparar el wsdl para consumirlo.

Incluso con las mejoras en la interoperativilidad de WSDL la herramienta de generación de proxis de C++ (sproxy) fallará con este WSDL debido a las opciones de seguridad que se incluyen en las secciones ws-policy. Para no tener este problema, haced una copia local de wsdl guardándolo desde el navegador. Entonces eliminad cualquier mención a las políticas.

Cliente Paso2. Generar un proxy C++ con sproxy

Abrimos una consola de Visual Studio (esto lo podemos hacer también desde Visual Studio en “Add Web Reference”, pero en la práctica parece haber algunas diferencias). Id al direcotrio donde guardamos el wsdl y escribimos el siguiente comando

>sproxy /wsdl  ArchivoWSDL.wsdl

Cliente Paso 3. Incluir el proxy en nuestro proyecto C++

Simplemente coged el contenido de los archivos generados anteriormente y pegadlos en un archivo de cabecera estándar de C++.

Cliente Paso 4. Llamad al servicio

El proxy generado usa CSoapSocketClientT para hacer las llamadas al servicio. Sin embargo podemos especificar un tipo diferente (ya que es conforme con el Arquetipo Cliente Soap de ATL), es decir, podemos usar CSoapWininetClient, este tipo se ha creado para usar comunicaciones seguras de manera que las credenciales cliente se pueden incluir automáticamente. Aunque mi cliente es sólo una aplicación de consola, y en el momento en el que deja de funcionar (No soy un experto en C++), consigue llamar al servicio y obtener la respuesta.

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);
                 {
                     CTestInterfaceT<CSoapWininetClient> cli;
                     int te;
                     HRESULT res= cli.MyOperation(&te);
                     cli.Cleanup();
                    }
   Uninitialize();
   return 0;
}

Y lo que tenemos aquí señoras y caballeros es un cliente en C++ no manegado llamando a un servicio WCF con seguridad y autenticación en el transporte!!!!!

Traducido por: Juan María Laó Ramos.

Artículo original.

Author: Juanma

Bueno, como reza el título de este blog y de las cosas que iré escribiendo ya os hareis una idea de cómo soy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: