Compartilhar via


Representando o cliente

O exemplo de representação demonstra como representar o aplicativo chamador no serviço para que o serviço possa acessar recursos do sistema em nome do chamador.

Este exemplo é baseado no exemplo de Host automático. Os arquivos de configuração do serviço e do cliente são iguais aos do exemplo de Host automático .

Observação

O procedimento de instalação e as instruções de compilação dessa amostra estão no final deste tópico.

O código de serviço foi modificado de modo que o Add método no serviço represente o chamador usando o OperationBehaviorAttribute conforme mostrado no código de exemplo a seguir.

[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, o contexto de segurança do thread em execução é alternado para representar o chamador antes de entrar no método Add e revertido ao sair do método.

O método DisplayIdentityInformation mostrado no código de exemplo a seguir é uma função de utilitário que exibe a identidade do chamador.

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;
}

O método Subtract no serviço representa o chamador usando chamadas imperativas, conforme mostrado no código de exemplo a seguir.

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;
}

Observe que, nesse caso, o chamador não é representado para toda a chamada, mas é representado apenas por uma parte da chamada. Em geral, representar o menor escopo é preferível à representação para toda a operação.

Os outros métodos não representam o chamador.

O código do cliente foi modificado para definir o nível de representação como Impersonation. O cliente especifica o nível de representação a ser usado pelo serviço usando a enumeração TokenImpersonationLevel. A enumeração dá suporte aos seguintes valores: None, Anonymouse IdentificationImpersonationDelegation. Para executar uma verificação de acesso ao acessar um recurso do sistema no computador local protegido usando ACLs do Windows, o nível de representação deve ser definido como Impersonation, conforme mostrado no código de exemplo a seguir.

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

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

Quando você executa a amostra, as solicitações de operação e as respostas são exibidas no serviço e na janela do console do cliente. Pressione ENTER em cada janela do console para desligar o serviço e o cliente.

Observação

O serviço deve ser executado em uma conta administrativa ou a conta em que ele é executado deve receber direitos para registrar o URI http://localhost:8000/ServiceModelSamples com a camada HTTP. Esses direitos podem ser concedidos configurando uma Reserva de Namespace usando a ferramenta Httpcfg.exe.

Observação

Em computadores que executam o Windows Server 2003, a representação só terá suporte se o aplicativo Host.exe tiver o privilégio de Representação. (Por padrão, somente os administradores têm essa permissão.) Para adicionar esse privilégio a uma conta na qual o serviço está em execução, vá para Ferramentas Administrativas, abra a Política de Segurança Local, abra Políticas Locais, clique em Atribuição de Direitos do Usuário, selecione Representar um Cliente após a Autenticação e clique duas vezes em Propriedades para adicionar um usuário ou grupo.

Para configurar, compilar, e executar o exemplo

  1. Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. Para compilar a edição .NET do C# ou do Visual Basic da solução, siga as instruções contidas em Como Compilar as Amostras do Windows Communication Foundation.

  3. Para executar a amostra em uma configuração de computador único ou entre computadores, siga as instruções contidas em Como Executar as Amostras do Windows Communication Foundation.

  4. Para demonstrar que o serviço representa o chamador, execute o cliente em uma conta diferente daquela em que o serviço está sendo executado. Para isso, digite no prompt de comando:

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

    O usuário é solicitado para uma senha. Insira a senha da conta especificada anteriormente.

  5. Ao executar o cliente, observe a identidade antes e depois de executá-la com credenciais diferentes.