Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O exemplo TrustedFacade demonstra como fluir as informações de identidade do chamador de um serviço para outro usando a infraestrutura de segurança do Windows Communication Foundation (WCF).
É um padrão de projeto comum expor a funcionalidade fornecida por um serviço à rede pública utilizando um serviço de fachada. O serviço de fachada normalmente reside na rede de perímetro (também conhecida como DMZ, zona desmilitarizada e sub-rede filtrada) e se comunica com um serviço de back-end que implementa a lógica de negócios e tem acesso a dados internos. O canal de comunicação entre o serviço de fachada e o serviço de back-end passa por um firewall e geralmente é limitado apenas para uma única finalidade.
Este exemplo consiste nos seguintes componentes:
Cliente da calculadora
Serviço de interface com calculadora
Serviço de infraestrutura da calculadora
O serviço de interface é responsável por validar o pedido e autenticar o originador. Após a autenticação e validação bem-sucedidas, ele encaminha a solicitação para o serviço de back-end usando o canal de comunicação controlado da rede de perímetro para a rede interna. Como parte da solicitação encaminhada, o serviço de fachada inclui informações sobre a identidade do chamador para que o serviço de back-end possa usar essas informações em seu processamento. A identidade do chamador é transmitida usando um Username token de segurança dentro do cabeçalho da mensagem Security . O exemplo usa a infraestrutura de segurança WCF para transmitir e extrair essas informações do Security cabeçalho.
Importante
O serviço de back-end confia no serviço de fachada para autenticar o chamador. Por isso, o serviço de back-end não autentica o chamador novamente; Utiliza as informações de identidade fornecidas pelo serviço de fachada no pedido encaminhado. Devido a esta relação de confiança, o serviço de backend deve autenticar o serviço de fachada para garantir que a mensagem encaminhada provenha de uma fonte confiável - neste caso, o serviço de fachada.
Execução
Há dois caminhos de comunicação neste exemplo. O primeiro é entre o cliente e o serviço de fachada, o segundo é entre o serviço de fachada e o serviço de backend.
Caminho de Comunicação entre o Cliente e o Serviço de Fachada
O caminho de comunicação do cliente para o serviço de fachada usa wsHttpBinding com tipo de credencial de cliente UserName. Isso significa que o cliente usa nome de utilizador e senha para autenticar ao serviço de fachada e o serviço de fachada usa o certificado X.509 para autenticar ao cliente. A configuração de vinculação se parece com o exemplo a seguir.
<bindings>
<wsHttpBinding>
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
O serviço de interface autentica o utilizador usando a implementação personalizada UserNamePasswordValidator. Para fins de demonstração, a autenticação apenas garante que o nome de usuário do chamador corresponda à senha apresentada. Na situação do mundo real, o utilizador provavelmente é autenticado usando o Active Directory ou um provedor de associação ASP.NET personalizado. A implementação do validador reside no FacadeService.cs arquivo.
public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// check that username matches password
if (null == userName || userName != password)
{
Console.WriteLine("Invalid username or password");
throw new SecurityTokenValidationException(
"Invalid username or password");
}
}
}
O validador personalizado é configurado para ser utilizado dentro do comportamento serviceCredentials no ficheiro de configuração do serviço de fachada. Esse comportamento também é usado para configurar o certificado X.509 do serviço.
<behaviors>
<serviceBehaviors>
<behavior name="FacadeServiceBehavior">
<!--The serviceCredentials behavior allows you to define -->
<!--a service certificate. -->
<!--A service certificate is used by the service to -->
<!--authenticate itself to its clients and to provide -->
<!--message protection. -->
<!--This configuration references the "localhost" -->
<!--certificate installed during the setup instructions. -->
<serviceCredentials>
<serviceCertificate
findValue="localhost"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
FacadeService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Caminho de comunicação entre o serviço de interface e o serviço de back-end
O caminho de comunicação entre o serviço de fachada e o serviço de back-end utiliza um customBinding que é composto por vários elementos de ligação. Esta vinculação realiza duas coisas. Ele autentica o serviço de fachada e o serviço de back-end para garantir que a comunicação seja segura e proveniente de uma fonte confiável. Além disso, ele também transmite a identidade do chamador inicial dentro do Username token de segurança. Nesse caso, apenas o nome de usuário do chamador inicial é transmitido para o serviço de back-end, a senha não é incluída na mensagem. Isso ocorre porque o serviço de back-end confia no serviço de fachada para autenticar o chamador antes de encaminhar a solicitação para ele. Como o serviço de fachada autentica-se junto ao serviço de back-end, o serviço de back-end pode confiar nas informações contidas na solicitação encaminhada.
A seguir está a configuração de ligação para esse caminho de comunicação.
<bindings>
<customBinding>
<binding name="ClientBinding">
<security authenticationMode="UserNameOverTransport"/>
<windowsStreamSecurity/>
<tcpTransport/>
</binding>
</customBinding>
</bindings>
O <elemento de vinculação de segurança> cuida da transmissão e extração do nome de usuário do chamador inicial. O windowsStreamSecurity< e><o tcpTransport> cuidam da autenticação de serviços de fachada e back-end e proteção de mensagens.
Para encaminhar a solicitação, a implementação do serviço de fachada deve fornecer o nome de usuário do chamador inicial para que a infraestrutura de segurança do WCF possa colocá-lo na mensagem encaminhada. O nome de utilizador do chamador inicial é fornecido na implementação do serviço de fachada, definindo-o na propriedade ClientCredentials na instância de proxy do cliente que o serviço de fachada utiliza para se comunicar com o serviço de back-end.
O seguinte código mostra como o método GetCallerIdentity é implementado no serviço de fachada. Outros métodos usam o mesmo padrão.
public string GetCallerIdentity()
{
CalculatorClient client = new CalculatorClient();
client.ClientCredentials.UserName.UserName = ServiceSecurityContext.Current.PrimaryIdentity.Name;
string result = client.GetCallerIdentity();
client.Close();
return result;
}
Como mostrado no código anterior, a senha não é definida na ClientCredentials propriedade, apenas o nome de usuário é definido. A infraestrutura de segurança do WCF cria um token de segurança de nome de usuário sem uma senha nesse caso, que é exatamente o que é necessário neste cenário.
No serviço de back-end, as informações contidas no token de segurança do utilizador precisam ser autenticadas. Por padrão, a segurança do WCF tenta mapear o usuário para uma conta do Windows usando a senha fornecida. Nesse caso, não há senha fornecida e o serviço de back-end não é necessário para autenticar o nome de usuário porque a autenticação já foi realizada pelo serviço de fachada. Para implementar esta funcionalidade no WCF, é fornecido um elemento personalizado UserNamePasswordValidator que impõe apenas que um nome de utilizador seja especificado no token e não executa nenhuma autenticação adicional.
public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// Ignore the password because it is empty,
// we trust the facade service to authenticate the client.
// Accept the username information here so that the
// application gets access to it.
if (null == userName)
{
Console.WriteLine("Invalid username");
throw new
SecurityTokenValidationException("Invalid username");
}
}
}
O validador personalizado é configurado para ser utilizado dentro do comportamento serviceCredentials no ficheiro de configuração do serviço de fachada.
<behaviors>
<serviceBehaviors>
<behavior name="BackendServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
BackendService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Para extrair as informações de nome de usuário e informações sobre a conta de serviço de fachada confiável, a implementação do serviço de back-end usa a ServiceSecurityContext classe. O código a seguir mostra como o GetCallerIdentity método é implementado.
public string GetCallerIdentity()
{
// Facade service is authenticated using Windows authentication.
//Its identity is accessible.
// On ServiceSecurityContext.Current.WindowsIdentity.
string facadeServiceIdentityName =
ServiceSecurityContext.Current.WindowsIdentity.Name;
// The client name is transmitted using Username authentication on
//the message level without the password
// using a supporting encrypted UserNameToken.
// Claims extracted from this supporting token are available in
// ServiceSecurityContext.Current.AuthorizationContext.ClaimSets
// collection.
string clientName = null;
foreach (ClaimSet claimSet in
ServiceSecurityContext.Current.AuthorizationContext.ClaimSets)
{
foreach (Claim claim in claimSet)
{
if (claim.ClaimType == ClaimTypes.Name &&
claim.Right == Rights.Identity)
{
clientName = (string)claim.Resource;
break;
}
}
}
if (clientName == null)
{
// In case there was no UserNameToken attached to the request.
// In the real world implementation the service should reject
// this request.
return "Anonymous caller via " + facadeServiceIdentityName;
}
return clientName + " via " + facadeServiceIdentityName;
}
As informações da conta de serviço de interface são extraídas usando a propriedade ServiceSecurityContext.Current.WindowsIdentity. Para acessar as informações sobre o chamador inicial, o serviço de back-end usa a ServiceSecurityContext.Current.AuthorizationContext.ClaimSets propriedade. Procura uma Identity reclamação com um tipo Name. Essa declaração é gerada automaticamente pela infraestrutura de segurança do WCF a partir das informações contidas no Username token de segurança.
Executando o exemplo
Quando você executa o exemplo, as solicitações de operação e as respostas são exibidas na janela do console do cliente. Pressione ENTER na janela do cliente para desligar o cliente. Você pode pressionar ENTER nas janelas do console dos serviços de fachada e de backend para desligar os serviços.
Username authentication required.
Provide a valid machine or domain ac
Enter username:
user
Enter password:
****
user via MyMachine\testaccount
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.
O ficheiro em lote Setup.bat incluído no exemplo do cenário de Façade confiável permite-lhe configurar o servidor com um certificado relevante para executar o serviço Facade que requer segurança baseada em certificado para se autenticar ao cliente. Consulte o procedimento de configuração no final deste tópico para obter detalhes.
A seguir apresentamos uma breve visão geral das diferentes seções dos arquivos em lote.
Criação do certificado do servidor.
As linhas a seguir do arquivo em lotes Setup.bat criam o certificado do servidor a ser usado.
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -peA
%SERVER_NAME%variável especifica o nome do servidor - o valor padrão é localhost. O certificado é armazenado no repositório LocalMachine.Instalar o certificado do serviço de fachada na loja de certificados de confiança do cliente.
A linha a seguir copia o certificado do serviço de fachada no repositório de pessoas confiáveis do cliente. Esta etapa é necessária porque os certificados gerados por Makecert.exe não são implicitamente confiáveis pelo sistema cliente. Se você já tiver um certificado enraizado em um certificado raiz confiável do cliente, por exemplo, um certificado emitido pela Microsoft, esta etapa de preencher o armazenamento de certificados do cliente com o certificado do servidor não será necessária.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
Para configurar, compilar e executar o exemplo
Verifique se você executou o procedimento de instalação do One-Time 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 a amostra na mesma máquina
Certifique-se de que o caminho inclui a pasta onde Makecert.exe está localizado.
Execute Setup.bat a partir da pasta de instalação de exemplo. Isso instala todos os certificados necessários para executar o exemplo.
Inicie o BackendService.exe do diretório \BackendService\bin em uma janela de console separada
Inicie o FacadeService.exe a partir do diretório \FacadeService\bin em uma janela de console separada
Inicie Client.exe a partir de \client\bin. A atividade do cliente é exibida no aplicativo de console do cliente.
Se o cliente e o serviço não puderem comunicar-se, consulte Dicas de Resolução de Problemas para Amostras de WCF.
Para limpar após a amostra
- Execute Cleanup.bat na pasta de exemplos depois de terminar de executar o exemplo.