Delegação e representação com WCF
A representação é uma técnica comum que os serviços usam para restringir o acesso do cliente aos recursos de um domínio de serviço. Os recursos do domínio de serviço podem ser recursos de máquina, como arquivos locais (representação), ou um recurso em outra máquina, como um compartilhamento de arquivos (delegação). Para um aplicativo de exemplo, consulte Representando o cliente. Para obter um exemplo de como usar a representação, consulte Como representar um cliente em um serviço.
Importante
Lembre-se de que, ao representar um cliente em um serviço, o serviço é executado com as credenciais do cliente, que podem ter privilégios mais altos do que o processo do servidor.
Descrição geral
Normalmente, os clientes chamam um serviço para que o serviço execute alguma ação em nome do cliente. A representação permite que o serviço atue como o cliente durante a execução da ação. A delegação permite que um serviço front-end encaminhe a solicitação do cliente para um serviço back-end de tal forma que o serviço back-end também possa representar o cliente. A representação é mais comumente usada como uma forma de verificar se um cliente está autorizado a executar uma determinada ação, enquanto a delegação é uma forma de fluir os recursos de representação, juntamente com a identidade do cliente, para um serviço de back-end. A delegação é um recurso de domínio do Windows que pode ser usado quando a autenticação baseada em Kerberos é executada. A delegação é distinta do fluxo de identidade e, como a delegação transfere a capacidade de se passar pelo cliente sem a posse da senha do cliente, é uma operação privilegiada muito maior do que o fluxo de identidade.
Tanto a representação quanto a delegação exigem que o cliente tenha uma identidade do Windows. Se um cliente não possui uma identidade do Windows, a única opção disponível é fluir a identidade do cliente para o segundo serviço.
Noções básicas de representação
O Windows Communication Foundation (WCF) oferece suporte à representação de uma variedade de credenciais de cliente. Este tópico descreve o suporte ao modelo de serviço para representar o chamador durante a implementação de um método de serviço. Também são discutidos cenários de implantação comuns envolvendo representação e segurança SOAP e opções WCF nesses cenários.
Este tópico se concentra na representação e delegação no WCF ao usar a segurança SOAP. Você também pode usar representação e delegação com WCF ao usar a segurança de transporte, conforme descrito em Usando representação com segurança de transporte.
Dois métodos
A segurança WCF SOAP tem dois métodos distintos para executar a representação. O método utilizado depende da ligação. Uma delas é a representação de um token do Windows obtido da SSPI (Security Support Provider Interface) ou da autenticação Kerberos, que é armazenada em cache no serviço. O segundo é a representação de um token do Windows obtido das extensões Kerberos, coletivamente chamado de Service-for-User (S4U).
Representação de token em cache
Você pode executar a representação de token em cache com o seguinte:
WSHttpBinding, WSDualHttpBindinge NetTcpBinding com uma credencial de cliente Windows.
BasicHttpBinding com um BasicHttpSecurityMode conjunto para a TransportWithMessageCredential credencial ou qualquer outra associação padrão em que o cliente apresente uma credencial de nome de usuário que o serviço pode mapear para uma conta válida do Windows.
Qualquer CustomBinding um que use uma credencial de cliente Windows com o
requireCancellation
definido comotrue
. (A propriedade está disponível nas seguintes classes: SecureConversationSecurityTokenParameters, SslSecurityTokenParameters, e SspiSecurityTokenParameters.) Se uma conversa segura for usada na associação, ela também deverá ter arequireCancellation
propriedade definida comotrue
.Qualquer um CustomBinding em que o cliente apresente uma credencial de nome de usuário. Se a conversação segura for usada na associação, ela também deverá ter a
requireCancellation
propriedade definida comotrue
.
Representação baseada em S4U
Você pode executar a representação baseada em S4U com o seguinte:
WSHttpBinding, WSDualHttpBindinge NetTcpBinding com uma credencial de cliente de certificado que o serviço pode mapear para uma conta válida do Windows.
Qualquer CustomBinding um que use uma credencial de cliente Windows com a
requireCancellation
propriedade definida comofalse
.Qualquer CustomBinding um que use um nome de usuário ou credencial de cliente Windows e conversa segura com a
requireCancellation
propriedade definida comofalse
.
A medida em que o serviço pode personificar o cliente depende dos privilégios que a conta de serviço detém quando tenta a falsificação de identidade, do tipo de representação usado e, possivelmente, da extensão da personificação que o cliente permite.
Nota
Quando o cliente e o serviço estão sendo executados no mesmo computador e o cliente está sendo executado em uma conta do sistema (por exemplo, Local System
ou Network Service
), o cliente não pode ser representado quando uma sessão segura é estabelecida com tokens de contexto de segurança com monitoração de estado. Um aplicativo de console ou formulário do Windows normalmente é executado na conta conectada no momento, para que a conta possa ser representada por padrão. No entanto, quando o cliente é uma página ASP.NET e essa página está hospedada no IIS 6.0 ou IIS 7.0, o cliente é executado sob a Network Service
conta por padrão. Todas as associações fornecidas pelo sistema que suportam sessões seguras usam um token de contexto de segurança (SCT) sem estado por padrão. No entanto, se o cliente for uma página ASP.NET e sessões seguras com SCTs com monitoração de estado forem usadas, o cliente não poderá ser representado. Para obter mais informações sobre como usar SCTs com monitoração de estado em uma sessão segura, consulte Como criar um token de contexto de segurança para uma sessão segura.
Representação em um método de serviço: modelo declarativo
A maioria dos cenários de representação envolve a execução do método de serviço no contexto do chamador. O WCF fornece um recurso de representação que facilita isso, permitindo que o usuário especifique o requisito de representação no OperationBehaviorAttribute atributo. Por exemplo, no código a seguir, a infraestrutura WCF representa o chamador antes de executar o Hello
método. Qualquer tentativa de acessar recursos nativos dentro do Hello
método será bem-sucedida somente se a lista de controle de acesso (ACL) do recurso permitir os privilégios de acesso do chamador. Para habilitar a ImpersonationOption representação, defina a Impersonation propriedade como um dos valores de enumeração, ou ImpersonationOption.RequiredImpersonationOption.Allowed, conforme mostrado no exemplo a seguir.
Nota
Quando um serviço tem credenciais mais altas do que o cliente remoto, as credenciais do serviço são usadas se a Impersonation propriedade estiver definida como Allowed. Ou seja, se um usuário com privilégios baixos fornecer suas credenciais, um serviço com privilégios mais altos executará o método com as credenciais do serviço e poderá usar recursos que, de outra forma, o usuário com privilégios baixos não poderia usar.
[ServiceContract]
public interface IHelloContract
{
[OperationContract]
string Hello(string message);
}
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
return "hello";
}
}
<ServiceContract()> _
Public Interface IHelloContract
<OperationContract()> _
Function Hello(ByVal message As String) As String
End Interface
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Return "hello"
End Function
End Class
A infraestrutura WCF pode representar o chamador somente se ele estiver autenticado com credenciais que podem ser mapeadas para uma conta de usuário do Windows. Se o serviço estiver configurado para autenticação usando uma credencial que não pode ser mapeada para uma conta do Windows, o método de serviço não será executado.
Nota
No Windows XP, a representação falhará se um SCT com estado for criado, resultando em um InvalidOperationExceptionarquivo . Para obter mais informações, consulte Cenários sem suporte.
Representação em um método de serviço: modelo imperativo
Às vezes, um chamador não precisa representar todo o método de serviço para funcionar, mas apenas uma parte dele. Nesse caso, obtenha a identidade do Windows do chamador dentro do método de serviço e execute imperativamente a representação. Faça isso usando a WindowsIdentity propriedade do ServiceSecurityContext para retornar uma instância da classe e chamando o Impersonate método antes de WindowsIdentity usar a instância.
Nota
Certifique-se de usar a instrução Visual BasicUsing
ou a instrução C# using
para reverter automaticamente a ação de representação. Se você não usar a instrução, ou se você usar uma linguagem de programação diferente de Visual Basic ou C#, certifique-se de reverter o nível de representação. Não fazer isso pode formar a base para a negação de serviço e elevação de ataques de privilégio.
public class HelloService : IHelloService
{
[OperationBehavior]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return "Hello";
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior()> _
Public Function Hello(ByVal message As String) As String _
Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = _
ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException( _
"The caller cannot be mapped to a WindowsIdentity")
End If
Dim cxt As WindowsImpersonationContext = callerWindowsIdentity.Impersonate()
Using (cxt)
' Access a file as the caller.
End Using
Return "Hello"
End Function
End Class
Representação para todos os métodos de serviço
Em alguns casos, você deve executar todos os métodos de um serviço no contexto do chamador. Em vez de habilitar explicitamente esse recurso por método, use o ServiceAuthorizationBehavior. Conforme mostrado no código a seguir, defina a ImpersonateCallerForAllOperations propriedade como true
. O ServiceAuthorizationBehavior é recuperado das coleções de comportamentos da ServiceHost classe. Observe também que a Impersonation
OperationBehaviorAttribute propriedade do aplicado a cada método também deve ser definida como ou AllowedRequired.
// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthorizationBehavior =
serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = true;
' Code to create a ServiceHost not shown.
Dim MyServiceAuthorizationBehavior As ServiceAuthorizationBehavior
MyServiceAuthorizationBehavior = serviceHost.Description.Behaviors.Find _
(Of ServiceAuthorizationBehavior)()
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = True
A tabela a seguir descreve o comportamento do WCF para todas as combinações possíveis de ImpersonationOption
e ImpersonateCallerForAllServiceOperations
.
ImpersonationOption |
ImpersonateCallerForAllServiceOperations |
Comportamento |
---|---|---|
Necessário | n/d | WCF personifica o chamador |
Permitido | false | O WCF não se faz passar pelo chamador |
Permitido | verdadeiro | WCF personifica o chamador |
Não permitido | false | O WCF não se faz passar pelo chamador |
Não permitido | verdadeiro | Não permitido. (Um InvalidOperationException é jogado.) |
Nível de representação obtido a partir de credenciais do Windows e representação de token em cache
Em alguns cenários, o cliente tem controle parcial sobre o nível de representação que o serviço executa quando uma credencial de cliente Windows é usada. Um cenário ocorre quando o cliente especifica um nível de representação Anônimo. O outro ocorre ao executar a representação com um token armazenado em cache. Isso é feito definindo a AllowedImpersonationLevelWindowsClientCredential propriedade da classe, que é acessada como uma propriedade da classe genérica ChannelFactory<TChannel> .
Nota
Especificar um nível de representação de Anonymous faz com que o cliente faça logon no serviço anonimamente. O serviço deve, portanto, permitir logons anônimos, independentemente de a falsificação de identidade ser realizada.
O cliente pode especificar o nível de representação como Anonymous, Identification, Impersonationou Delegation. Apenas um token no nível especificado é produzido, conforme mostrado no código a seguir.
ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
Dim cf As ChannelFactory(Of IEcho) = New ChannelFactory(Of IEcho)("EchoEndpoint")
cf.Credentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Impersonation
A tabela a seguir especifica o nível de representação que o serviço obtém ao representar a partir de um token armazenado em cache.
AllowedImpersonationLevel valor |
Serviço tem SeImpersonatePrivilege |
Serviço e cliente são capazes de delegação | Token armazenado em cache ImpersonationLevel |
---|---|---|---|
Anónimo | Sim | n/d | Falsificação de identidade |
Anónimo | No | n/d | Identificação |
Identificação | n/d | n/d | Identificação |
Falsificação de identidade | Sim | n/d | Falsificação de identidade |
Falsificação de identidade | No | n/d | Identificação |
Delegação | Sim | Sim | Delegação |
Delegação | Sim | No | Falsificação de identidade |
Delegação | No | n/d | Identificação |
Nível de representação obtido a partir de credenciais de nome de usuário e representação de token armazenado em cache
Ao passar o serviço seu nome de usuário e senha, um cliente permite que o WCF faça logon como esse usuário, o que equivale a definir a AllowedImpersonationLevel
propriedade como Delegation. (O AllowedImpersonationLevel
está disponível nas WindowsClientCredential e HttpDigestClientCredential aulas.) A tabela a seguir fornece o nível de representação obtido quando o serviço recebe credenciais de nome de usuário.
AllowedImpersonationLevel |
Serviço tem SeImpersonatePrivilege |
Serviço e cliente são capazes de delegação | Token armazenado em cache ImpersonationLevel |
---|---|---|---|
n/d | Sim | Sim | Delegação |
n/d | Sim | No | Falsificação de identidade |
n/d | No | n/d | Identificação |
Nível de representação obtido da representação baseada em S4U
Serviço tem SeTcbPrivilege |
Serviço tem SeImpersonatePrivilege |
Serviço e cliente são capazes de delegação | Token armazenado em cache ImpersonationLevel |
---|---|---|---|
Sim | Sim | n/d | Falsificação de identidade |
Sim | No | n/d | Identificação |
No | n/d | n/d | Identificação |
Mapeando um certificado de cliente para uma conta do Windows
É possível que um cliente se autentique em um serviço usando um certificado e que o serviço mapeie o cliente para uma conta existente por meio do Ative Directory. O XML a seguir mostra como configurar o serviço para mapear o certificado.
<behaviors>
<serviceBehaviors>
<behavior name="MapToWindowsAccount">
<serviceCredentials>
<clientCertificate>
<authentication mapClientCertificateToWindowsAccount="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
O código a seguir mostra como configurar o serviço.
// Create a binding that sets a certificate as the client credential type.
WSHttpBinding b = new WSHttpBinding();
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
// Create a service host that maps the certificate to a Windows account.
Uri httpUri = new Uri("http://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;
Delegação
Para delegar a um serviço back-end, um serviço deve executar Kerberos multi-leg (SSPI sem fallback NTLM) ou autenticação direta Kerberos para o serviço back-end usando a identidade Windows do cliente. Para delegar a um serviço de back-end, crie um ChannelFactory<TChannel> e um canal e, em seguida, comunique através do canal enquanto se faz passar pelo cliente. Com essa forma de delegação, a distância na qual o serviço back-end pode ser localizado do serviço front-end depende do nível de representação alcançado pelo serviço front-end. Quando o nível de representação é Impersonation, os serviços front-end e back-end devem estar em execução na mesma máquina. Quando o nível de representação é Delegation, os serviços front-end e back-end podem estar em máquinas separadas ou na mesma máquina. Habilitar a representação no nível de delegação requer que a diretiva de domínio do Windows seja configurada para permitir a delegação. Para obter mais informações sobre como configurar o Ative Directory para suporte de delegação, consulte Habilitando a autenticação delegada.
Nota
Quando um cliente se autentica no serviço front-end usando um nome de usuário e senha que correspondem a uma conta do Windows no serviço back-end, o serviço front-end pode autenticar no serviço back-end reutilizando o nome de usuário e a senha do cliente. Essa é uma forma particularmente poderosa de fluxo de identidade, porque passar nome de usuário e senha para o serviço back-end permite que o serviço back-end execute a representação, mas não constitui delegação porque Kerberos não é usado. Os controles do Ative Directory na delegação não se aplicam à autenticação de nome de usuário e senha.
Capacidade de delegação em função do nível de representação
Nível de representação | O serviço pode executar a delegação entre processos | O serviço pode executar a delegação entre máquinas |
---|---|---|
Identification | No | No |
Impersonation | Sim | No |
Delegation | Sim | Sim |
O exemplo de código a seguir demonstra como usar a delegação.
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
EndpointAddress backendServiceAddress = new EndpointAddress("http://localhost:8000/ChannelApp");
// Any binding that performs Windows authentication of the client can be used.
ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
IHelloService channel = channelFactory.CreateChannel();
return channel.Hello(message);
}
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException("The caller cannot be mapped to a Windows identity.")
End If
Dim backendServiceAddress As EndpointAddress = New EndpointAddress("http://localhost:8000/ChannelApp")
' Any binding that performs Windows authentication of the client can be used.
Dim channelFactory As ChannelFactory(Of IHelloService) = _
New ChannelFactory(Of IHelloService)(New NetTcpBinding(), backendServiceAddress)
Dim channel As IHelloService = channelFactory.CreateChannel()
Return channel.Hello(message)
End Function
End Class
Como configurar um aplicativo para usar delegação restrita
Antes de poder usar a delegação restrita, o remetente, o recetor e o controlador de domínio devem ser configurados para isso. O procedimento a seguir lista as etapas que permitem a delegação restrita. Para obter detalhes sobre as diferenças entre delegação e delegação restrita, consulte a parte das Extensões Kerberos do Windows Server 2003 que discute a discussão restrita.
No controlador de domínio, desmarque a caixa de seleção Conta é confidencial e não pode ser delegada para a conta na qual o aplicativo cliente está sendo executado.
No controlador de domínio, marque a caixa de seleção Conta é confiável para delegação para a conta na qual o aplicativo cliente está sendo executado.
No controlador de domínio, configure o computador de camada intermediária para que seja confiável para delegação, clicando na opção Confiar no computador para delegação .
No controlador de domínio, configure o computador de camada intermediária para usar a delegação restrita, clicando na opção Confiar neste computador para delegação somente a serviços especificados.
Para obter instruções mais detalhadas sobre como configurar a delegação restrita, consulte Transição do protocolo Kerberos e Delegação restrita.
Consulte também
- OperationBehaviorAttribute
- Impersonation
- ImpersonationOption
- WindowsIdentity
- ServiceSecurityContext
- WindowsIdentity
- ServiceAuthorizationBehavior
- ImpersonateCallerForAllOperations
- ServiceHost
- AllowedImpersonationLevel
- WindowsClientCredential
- ChannelFactory<TChannel>
- Identification
- Usando a representação com segurança de transporte
- Fazer-se passar pelo Cliente
- Como: Representar um cliente em um serviço
- Ferramenta Utilitário de Metadados ServiceModel (Svcutil.exe)