with clientcredentials clientcertificate .net wcf wcf-security wcf-binding wcf-sessions

.net - with - clientcredentials clientcertificate certificate c#



Sesiones de WCF con un wsHttpBinding y sin seguridad de Windows (2)

OMI esto es lo que sucede cuando estás usando una tecnología con una abstracción pobre sobre HTTP como WCF. El hecho de que los servicios web de WCF en teoría podrían alojarse sin HTTP (es decir, a través de TCP NET, MSMQ, etc.) simplemente dificulta el uso de funciones incorporadas de HTTP sin entrar en el infierno de la configuración y comenzar un juego de "adivinar la configuración correcta" por prueba y error "donde prueba todas las configuraciones posibles de permutación hasta que encuentre la correcta que funcione!

En última instancia, si no puede utilizar WCF y tiene que implementar el servicio web desde cero, simplemente establecerá una cookie cuando el cliente se haya autenticado correctamente. Luego, con cada solicitud del cliente, simplemente tome la información de sesión a la que hace referencia esa cookie.

Una posible solución si tuviera que usar WCF es tomar la gestión de la sesión en sus propias manos (es lo que hago cuando no estoy satisfecho con el esfuerzo requerido para hacer que algo funcione) y tener una propiedad explícita de "sesión" en toda su web servicios que requieren una sesión / autenticación (generalmente un guid generado en la Autenticación). Entonces, para cada solicitud posterior, utiliza el guid para rehidratar la información de sesión asociada con ese cliente.

Si está interesado en probar diferentes marcos de servicios web, tengo un Framework de servicios web de código abierto que le permite crear servicios web sin configuración, DRY y comprobables donde (sin ninguna configuración requerida) cada servicio web que crea es automáticamente accesible a través de REST Puntos finales XML, JSON, JSV, SOAP 1.1, SOAP 1.2. Efectivamente, le permite acceder a su mismo servicio web a través de una url HTTP GET para clientes REST-ful y fácil depuración, así como puntos finales SOAP (una opción popular que todavía imponen algunas empresas). El tutorial de Hello World debería darle una buena visión general de algunas de sus características y cómo funciona.

Necesito crear un servicio WCF alojado en IIS, utiliza el transporte HTTP y el estado de espera en la memoria del servidor. Si bien soy consciente de que los servicios con estado no son una buena idea, esta última restricción es necesaria para que el servicio funcione con un cliente heredado.

Lo primero que pensé fue en la sesión de asp.net para almacenar los valores. Activé el modo de compatibilidad asp.net en mi servicio, lo que me dio acceso al HttpContext, pero los valores que se colocaron en el objeto de sesión no se conservaban en la memoria. Supongo que esto se debió a que el módulo http que maneja el estado de la sesión no estaba configurado correctamente, pero cuando busqué la respuesta en Google, me encontré con las sesiones de WCF y pensé que podría ser una mejor idea usarlas.

Sin embargo, las sesiones de WCF parecen tener un bajo nivel de documentación y colocar un extraño conjunto de requisitos previos en un servicio, y no he podido encontrar una configuración que satisfaga mis necesidades: debe estar alojado en IIS, debe usar transporte http o https y puede No respondo en la autenticación de Windows porque el cliente y el servidor no formarán parte del mismo dominio. Estoy tratando de hacer esto usando wsHttpBinding, había escuchado que las sesiones de WCF requerían seguridad o mensaje confiable, pero: - Usando el enlace estándar y cuando los servidores no son parte del mismo dominio falla con una "SecurityNegotiationException The calling no fue autenticado por la excepción de "servicio". Esto es bastante lógico ya que usaba la seguridad de Windows.

  • Si desactivo la seguridad completa, falla con un "Contrato requiere sesión, pero el enlace ''WSHttpBinding'' no lo admite o no está configurado correctamente para admitirlo."

  • Si, al tiempo que mantengo la seguridad deshabilitada, habilito el mensaje confiable. Obtengo la excepción "Falló la validación de enlace porque WSHttpBinding no admite sesiones confiables sobre la seguridad del transporte (HTTPS). La fábrica de canales o el host de servicio no se pudieron abrir. Use la seguridad de los mensajes para enviar mensajes seguros y confiables a través de HTTP ".

  • Intenté habilitar la seguridad del nivel de transporte, pero esto no parece hacer ninguna diferencia en el error generado

¿Hay alguna configuración que pueda funcionar para mí? ¿O debería volver al plan de usar sesiones de asp.net?


Puede hacer que WCF mantenga la información de la sesión en la memoria de una manera bastante simple. Para eliminar cualquier posible influencia externa en mis instrucciones, asumiré que está comenzando con un nuevo proyecto:

  1. Cree un nuevo proyecto de biblioteca de servicios WCF. Este proyecto ya incluirá un servicio con un enlace WSHttpBiding preconfigurado.
  2. Vaya al contrato de servicio (IService1.cs) y cambie el atributo ServiceContract a lo siguiente:

    [ServiceContract(SessionMode = SessionMode.Required)]

  3. Vaya a la implementación del servicio (Service1.cs) y agregue el siguiente atributo ServiceBehavior a la clase de servicio ( Service1 ):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]

  4. Agregar datos de sesión como miembros de la clase de servicio ( Service1 ):

    public class Service1 : IService1 { ... private string UserFullName { get; set; } ... }

  5. Use los miembros para presentar datos específicos de la sesión (recuerde también agregarlos al contrato de servicio, IService1 ):

    public class Service1 : IService1 { ... public string Welcome(string fullName) { UserFullName = fullName ?? "Guest"; return string.Format("Welcome back, {0}!", UserFullName); } public string Goodbye() { return string.Format("Come back soon, {0}!", UserFullName ?? "Guest"); } ... }

SessionMode.Required asegura que sus clientes sean rastreados por la sesión.
InstanceContextMode.PerSession garantiza que se crea una instancia de su clase de servicio (Service1) para cada sesión, de modo que puede retener los datos de la sesión en ella y existirá en la memoria en varias llamadas en la misma sesión.
ConcurrencyMode.Single garantiza que solo un subproceso puede ingresar a cada instancia de clase de servicio (Service1) y evita posibles problemas de concurrencia si solo accede a datos de la clase de servicio (y ubicaciones externas seguras para subprocesos).

EDITAR: de forma predeterminada, WSHttpBinding solo permite sesiones de seguridad. Pero también admite sesiones fiables, que permiten establecer sesiones sin seguridad habilitada. La siguiente configuración de enlace desactiva la seguridad y permite sesiones confiables:

<wsHttpBinding> <binding name="wsHttpBindingConfiguration"> <security mode="None" /> <reliableSession enabled="true" /> </binding> </wsHttpBinding>