Las operaciones de servicio WCF invocadas asincrónicamente a través de servidores proxy de cliente compartidos mediante suplantación pueden usar el contexto de suplantación incorrecto

Este artículo le ayuda a resolver el problema de que las operaciones de servicio Windows Communication Foundation (WCF) invocadas asincrónicamente a través de servidores proxy de cliente compartidos mediante suplantación pueden usar el contexto de suplantación incorrecto.

Versión del producto original:   Windows Communication Foundation
Número KB original:   2856654

Síntomas

Imagine la siguiente situación:

  • El cliente usa servidores proxy WCF para invocar operaciones de servicio.

  • El cliente se basa en los servidores proxy de cliente para abrir automáticamente.

  • El cliente usa la suplantación.

  • El cliente invoca las operaciones de forma asincrónica.

  • Se reutiliza la misma instancia de proxy de cliente para varios usos.

En este escenario, puede encontrar situaciones en las que la operación de servicio no se ejecuta en el contexto de suplantación previsto.

No se produce ninguna excepción o se registra un error debido a la pérdida del contexto de suplantación. Si la operación se ejecuta correctamente o no depende de lo que intente hacer la operación de servicio. Los posibles errores observados serán errores de autorización al intentar ejecutar código de cliente dentro de la operación de servicio.

Una forma de diagnosticar este problema es comprobar el contenido de ServiceSecurityContext.Current.WindowsIdentity la operación de servicio. Si la identidad es intermitentemente diferente de lo que espera, es posible que encuentre este problema.

Causa

Para que un proxy de cliente pueda invocar una operación, debe abrirse. Se puede abrir explícitamente desde su propio código o puede confiar en WCF para abrirse automáticamente.

El problema se produce porque la apertura automática necesaria para operaciones asincrónicas se realiza de forma asincrónica. Y cuando se usa el mismo proxy para varias operaciones asincrónicas, todos menos el primero deben esperar a que la operación asincrónica inicial se haga correctamente. Según los subprocesos que invocan estas operaciones y el tiempo, es posible que se pierda el contexto de suplantación presente para la primera apertura automática.

Solución

La solución a este problema es sencilla: no confíe en la apertura automática, sino que abra explícitamente el proxy de cliente usted mismo.

Al abrir el proxy de cliente usted mismo, se asegura de que las conexiones subyacentes están completamente abiertas en el contexto de suplantación correcto antes de invocar la primera operación.

Este es un ejemplo que muestra lo recomendado client.Open() explícitamente.

public static void Main(string[] args)
{
    NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;

    string address = "net.tcp://localhost:8887/EchoService/svc";
    Service1Client client = new Service1Client(binding, new EndpointAddress(address));

    // Explicit open is required when using async client operations with impersonation
    using (Impersonation p = new Impersonation("myDomain", "myUser", "myPassword"))
    {
        client.Open();
    }

    for (int i = 0; i < 10; ++i)
    {
        ThreadPool.QueueUserWorkItem((state) =>
        {
            using (Impersonation p = new Impersonation("myDomain", "myUser", "myPassword"))
            {
                client.BeginGetData(new GetDataRequest((int) state), (ar) =>
                {
                    GetDataResponse response = client.EndGetData(ar);
                    Console.WriteLine("Response was: '{0}'", response.GetDataResult);
                }, null);
            }
        }, i);
    }

    Console.WriteLine("Press ENTER...");
    Console.ReadLine();
    Environment.Exit(0);
}

Más información

La apertura explícita de servidores proxy de cliente cuando se comparten y se usan de forma asincrónica se considera un procedimiento recomendado por varias razones. Puede obtener más información en Procedimientos recomendados: abrasiempre el proxy de cliente WCF explícitamente cuando se comparta .