Compartir vía


Suplantar el cliente

El ejemplo de Suplantación muestra cómo suplantar la aplicación de llamador en el servicio para que el servicio pueda tener acceso a los recursos del sistema en nombre del llamador.

Este ejemplo se basa en el ejemplo de hospedaje automático. Los archivos de configuración de cliente y servicio son iguales que los del ejemplo autohospedado.

Nota

El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.

El código del servicio se ha modificado de tal modo que el método Add en el servicio suplanta al llamador mediante OperationBehaviorAttribute como se muestra en el código muestra siguiente.

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public double Add(double n1, double n2)
{
    double result = n1 + n2;
    Console.WriteLine("Received Add({0},{1})", n1, n2);
    Console.WriteLine("Return: {0}", result);
    DisplayIdentityInformation();
    return result;
}

Como resultado, el contexto de seguridad del subproceso que se está ejecutando se intercambia para suplantar al llamador antes de entrar al método Add y revierte en la salida del método.

El método DisplayIdentityInformation mostrado en el código muestra siguiente es una función de utilidad que muestra la identidad del llamador.

static void DisplayIdentityInformation()
{
    Console.WriteLine("\t\tThread Identity            :{0}",
         WindowsIdentity.GetCurrent().Name);
    Console.WriteLine("\t\tThread Identity level  :{0}",
         WindowsIdentity.GetCurrent().ImpersonationLevel);
    Console.WriteLine("\t\thToken                     :{0}",
         WindowsIdentity.GetCurrent().Token.ToString());
    return;
}

El método Subtract en el servicio suplanta al llamador utilizando las llamadas imperativas, tal y como se muestra en el código muestra siguiente.

public double Subtract(double n1, double n2)
{
    double result = n1 - n2;
    Console.WriteLine("Received Subtract({0},{1})", n1, n2);
    Console.WriteLine("Return: {0}", result);
    Console.WriteLine("Before impersonating");
    DisplayIdentityInformation();

    if (ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||
        ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Delegation)
    {
        // Impersonate.
        using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
        {
            // Make a system call in the caller's context and ACLs
            // on the system resource are enforced in the caller's context.
            Console.WriteLine("Impersonating the caller imperatively");
            DisplayIdentityInformation();
        }
    }
    else
    {
        Console.WriteLine("ImpersonationLevel is not high enough to perform this operation.");
    }

    Console.WriteLine("After reverting");
    DisplayIdentityInformation();
    return result;
}

Tenga en cuenta que en este caso que el llamador no se suplanta para la llamada completa, sino que sólo se suplanta para una parte de la llamada. En general, la suplantación para el ámbito más pequeño es preferible a la suplantación para la operación completa.

Los otros métodos no suplantan al llamador.

El código de cliente se ha modificado para establecer el nivel de suplantación en Impersonation. El cliente especifica el nivel de suplantación que el servicio va a utilizar, mediante la enumeración TokenImpersonationLevel. La enumeración admite los valores siguientes: None, Anonymous, Identification, Impersonation y Delegation. Para realizar una comprobación de acceso al tener acceso a un recurso del sistema en el equipo local que se protege utilizando ACL de Windows, el nivel de suplantación debe estar establecido en Impersonation, como se muestra en el código muestra siguiente.

// Create a client with given client endpoint configuration
CalculatorClient client = new CalculatorClient();

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

Al ejecutar el ejemplo, las solicitudes y las respuestas de operación se muestran tanto en la ventanas de la consola del cliente como del servicio. Presione Entrar en cada ventana de la consola para cerrar el servicio y el cliente.

Nota

El servicio se debe ejecutar en una cuenta administrativa, o bien la cuenta en que se ejecuta debe tener derechos para registrar el URI http://localhost:8000/ServiceModelSamples con la capa HTTP. Es posible conceder tales derechos al configurar una Reserva de espacio de nombres mediante la herramienta Httpcfg.exe.

Nota

En los equipos que ejecutan Windows Server 2003, la suplantación se admite solo si la aplicación Host.exe tiene el privilegio de Suplantación. (De manera predeterminada, solo los administradores tienen este permiso). Para agregar este privilegio a una cuenta como la que el servicio ejecuta, vaya a Herramientas administrativas, abra Directiva de seguridad local, abra Directivas locales, haga clic en Asignación de derechos de usuario, seleccione Suplantar a un cliente tras la autenticación y haga doble clic en Propiedades para agregar un usuario o grupo.

Configurar, compilar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Para compilar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Building the Windows Communication Foundation Samples.

  3. Para ejecutar el ejemplo en una configuración de una sola máquina o de varias máquinas, siga las instrucciones que se indican en Ejecución de los ejemplos de Windows Communication Foundation.

  4. Para mostrar que el servicio suplanta al llamador, ejecute el cliente bajo una cuenta diferente de aquella bajo la cual el servicio se está ejecutando. Para realizar esta operación, en el símbolo del sistema, escriba:

    runas /user:<machine-name>\<user-name> client.exe
    

    Se solicita a continuación una contraseña. Escriba previamente la contraseña para la cuenta que especificó.

  5. Al ejecutar el cliente, tenga en cuenta la identidad de antes y de después de ejecutarlo con credenciales diferentes.