Fazer-se passar pelo Cliente
O exemplo de representação demonstra como representar o aplicativo chamador no serviço para que o serviço possa acessar os recursos do sistema em nome do chamador.
Este exemplo é baseado no exemplo Self-Host . Os arquivos de configuração de serviço e cliente são os mesmos do exemplo Self-Host.
Nota
O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.
O código de serviço foi modificado de modo que o Add
método no serviço representa o chamador usando o OperationBehaviorAttribute como 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 de execução é alternado para representar o chamador antes de entrar no Add
método e revertido ao sair do método.
O DisplayIdentityInformation
método 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 Subtract
método 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, neste caso, o chamador não é representado para toda a chamada, mas apenas para uma parte da chamada. Em geral, representar para o menor escopo é preferível a personificar 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 TokenImpersonationLevel enumeração. A enumeração suporta os seguintes valores: None, Anonymous, IdentificationImpersonation e Delegation. Para executar uma verificação de acesso ao acessar um recurso do sistema na máquina local protegida 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 o exemplo, as solicitações de operação e as respostas são exibidas nas janelas do console de serviço e do cliente. Pressione ENTER em cada janela do console para desligar o serviço e o cliente.
Nota
O serviço deve ser executado em uma conta administrativa ou a conta sob a qual ele é executado deve receber direitos para registrar o http://localhost:8000/ServiceModelSamples
URI com a camada HTTP. Esses direitos podem ser concedidos configurando uma Reserva de Namespace usando a ferramenta Httpcfg.exe.
Nota
Em computadores que executam o Windows Server 2003, a representação é suportada somente se o aplicativo Host.exe tiver o privilégio de representação. (Por padrão, apenas os administradores têm essa permissão.) Para adicionar esse privilégio a uma conta na qual o serviço está sendo executado, vá para Ferramentas Administrativas, abra Diretiva de Segurança Local, abra Diretivas Locais, clique em Atribuição de Direitos de Usuário e selecione Representar um Cliente após Autenticação e clique duas vezes em Propriedades para adicionar um usuário ou grupo.
Para configurar, compilar e executar o exemplo
Certifique-se de ter executado o procedimento de instalação única para os exemplos do Windows Communication Foundation.
Para criar a edição C# ou Visual Basic .NET da solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração de máquina única ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation.
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 fazer isso, no prompt de comando, digite:
runas /user:<machine-name>\<user-name> client.exe
Em seguida, ser-lhe-á solicitada uma palavra-passe. Introduza a palavra-passe da conta que especificou anteriormente.
Ao executar o cliente, anote a identidade antes e depois de executá-lo com credenciais diferentes.