Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O exemplo DurableIssuedTokenProvider demonstra como implementar um provedor de token emitido pelo cliente personalizado.
Discussão
Um provedor de token no Windows Communication Foundation (WCF) é usado para fornecer credenciais à infraestrutura de segurança. O provedor de token em geral examina o destino e emite as credenciais apropriadas para que a infraestrutura de segurança possa proteger a mensagem. O WCF também é fornecido com um provedor de token CardSpace. Os provedores de token personalizado são úteis nos seguintes casos:
Se você tiver um repositório de credenciais com o qual o provedor de token interno não pode operar.
Se você quiser fornecer seu próprio mecanismo personalizado para transformar as credenciais do ponto em que o usuário fornece os detalhes para quando o cliente WCF usa as credenciais.
Se você estiver criando um token personalizado.
Este exemplo mostra como criar um provedor de token personalizado que armazena em cache tokens emitidos por um STS (Serviço de Token de Segurança).
Para resumir, este exemplo demonstra o seguinte:
Como um cliente pode ser configurado com um provedor de token personalizado.
Como os tokens emitidos podem ser armazenados em cache e fornecidos ao cliente WCF.
Como o servidor é autenticado pelo cliente usando o certificado X.509 do servidor.
Este exemplo consiste em um programa de console do cliente (Client.exe), um programa de console de serviço de token de segurança (Securitytokenservice.exe) e um programa de console de serviço (Service.exe). O serviço implementa um contrato que define um padrão de comunicação solicitação-resposta. O contrato é definido pela ICalculator interface, que expõe operações matemáticas (adicionar, subtrair, multiplicar e dividir). O cliente obtém um token de segurança do STS (Serviço de Token de Segurança) e faz solicitações síncronas ao serviço para uma determinada operação matemática e o serviço responde com o resultado. A atividade do cliente é visível na janela do console.
Observação
O procedimento de configuração e as instruções de build para este exemplo estão localizados no final deste tópico.
Este exemplo expõe o contrato ICalculator usando o <wsHttpBinding>. A configuração dessa associação no cliente é mostrada no código a seguir.
<bindings>
<wsFederationHttpBinding>
<binding name="ServiceFed">
<security mode="Message">
<message issuedKeyType="SymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address="http://localhost:8000/sts/windows"
binding="wsHttpBinding" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
No elemento security de wsFederationHttpBinding, o valor mode configura qual modo de segurança deve ser usado. Neste exemplo, a segurança de mensagens está sendo usada, por isso o elemento message de wsFederationHttpBinding é especificado dentro do elemento security de wsFederationHttpBinding. O elemento issuer de wsFederationHttpBinding dentro do elemento message de wsFederationHttpBinding especifica o endereço e a associação para o Serviço de Token de Segurança que emite um token de segurança para o cliente para que o cliente possa se autenticar no serviço calculadora.
A configuração dessa associação no serviço é mostrada no código a seguir.
<bindings>
<wsFederationHttpBinding>
<binding name="ServiceFed">
<security mode="Message">
<message issuedKeyType="SymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuerMetadata address="http://localhost:8000/sts/mex">
<identity>
<certificateReference storeLocation="CurrentUser"
storeName="TrustedPeople"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=STS" />
</identity>
</issuerMetadata>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
No elemento security de wsFederationHttpBinding, o valor mode configura qual modo de segurança deve ser usado. Neste exemplo, a segurança de mensagens está sendo usada, por isso o elemento message de wsFederationHttpBinding é especificado dentro do elemento security de wsFederationHttpBinding. O elemento issuerMetadata de wsFederationHttpBinding dentro do elemento message de wsFederationHttpBinding especifica o endereço e a identidade de um ponto de extremidade que pode ser usado para recuperar metadados do Serviço de token de segurança.
O comportamento do serviço é mostrado no código a seguir.
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<issuedTokenAuthentication>
<knownCertificates>
<add storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=STS" />
</knownCertificates>
</issuedTokenAuthentication>
<serviceCertificate storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=localhost" />
</serviceCredentials>
</behavior>
O issuedTokenAuthentication elemento dentro do serviceCredentials elemento permite que o serviço especifique restrições nos tokens que permite que os clientes apresentem durante a autenticação. Essa configuração especifica que os tokens assinados por um certificado cujo Nome do Sujeito é CN=STS são aceitos pelo serviço.
O Serviço de token de segurança expõe um único ponto de extremidade usando o wsHttpBinding padrão. O Serviço de Token de Segurança responde à solicitação de clientes para tokens e, desde que o cliente se autentique usando uma conta do Windows, emite um token que contém o nome de usuário do cliente como uma declaração no token emitido. Como parte da criação do token, o Serviço de Token de Segurança assina o token usando a chave privada associada ao certificado CN=STS. Além disso, ele cria uma chave simétrica e a criptografa usando a chave pública associada ao certificado CN=localhost. Ao retornar o token ao cliente, o Serviço de Token de Segurança também retorna a chave simétrica. O cliente apresenta o token emitido para o serviço Calculadora e prova que ele conhece a chave simétrica assinando a mensagem com essa chave.
Credenciais de cliente personalizadas e provedor de token
As etapas a seguir mostram como desenvolver um provedor de token personalizado que armazena tokens emitidos em cache e os integra ao WCF: segurança.
Para desenvolver um provedor de token personalizado
Escreva um provedor de token personalizado.
O exemplo implementa um provedor de token personalizado que retorna um token de segurança recuperado de um cache.
Para executar essa tarefa, o provedor de token personalizado deriva a SecurityTokenProvider classe e substitui o GetTokenCore método. Esse método tenta obter um token do cache ou, se um token não puder ser encontrado no cache, recupera um token do provedor subjacente e, em seguida, armazena esse token em cache. Em ambos os casos, o método retorna um
SecurityToken.protected override SecurityToken GetTokenCore(TimeSpan timeout) { GenericXmlSecurityToken token; if (!this.cache.TryGetToken(target, issuer, out token)) { token = (GenericXmlSecurityToken) this.innerTokenProvider.GetToken(timeout); this.cache.AddToken(token, target, issuer); } return token; }Escreva o gerenciador de tokens de segurança personalizado.
O SecurityTokenManager é usado para criar um SecurityTokenProvider para um SecurityTokenRequirement específico que é passado para ele no método
CreateSecurityTokenProvider. O gerenciador de tokens de segurança também é usado para criar autenticadores de token e serializadores de token, mas eles não são cobertos por este exemplo. Neste exemplo, o gerenciador de tokens de segurança personalizado herda da classe ClientCredentialsSecurityTokenManager e substitui o métodoCreateSecurityTokenProviderpara retornar o provedor de token personalizado quando os requisitos de token passados indicam que um token emitido é solicitado.class DurableIssuedTokenClientCredentialsTokenManager : ClientCredentialsSecurityTokenManager { IssuedTokenCache cache; public DurableIssuedTokenClientCredentialsTokenManager ( DurableIssuedTokenClientCredentials creds ): base(creds) { this.cache = creds.IssuedTokenCache; } public override SecurityTokenProvider CreateSecurityTokenProvider ( SecurityTokenRequirement tokenRequirement ) { if (IsIssuedSecurityTokenRequirement(tokenRequirement)) { return new DurableIssuedSecurityTokenProvider ((IssuedSecurityTokenProvider)base.CreateSecurityTokenProvider( tokenRequirement), this.cache); } else { return base.CreateSecurityTokenProvider(tokenRequirement); } } }Escreva uma credencial de cliente personalizada.
Uma classe de credenciais de cliente é usada para representar as credenciais configuradas para o proxy do cliente e cria o gerenciador de tokens de segurança usado para obter autenticadores de token, provedores de token e serializadores de token.
public class DurableIssuedTokenClientCredentials : ClientCredentials { IssuedTokenCache cache; public DurableIssuedTokenClientCredentials() : base() { } DurableIssuedTokenClientCredentials ( DurableIssuedTokenClientCredentials other) : base(other) { this.cache = other.cache; } public IssuedTokenCache IssuedTokenCache { get { return this.cache; } set { this.cache = value; } } protected override ClientCredentials CloneCore() { return new DurableIssuedTokenClientCredentials(this); } public override SecurityTokenManager CreateSecurityTokenManager() { return new DurableIssuedTokenClientCredentialsTokenManager ((DurableIssuedTokenClientCredentials)this.Clone()); } }Implemente o cache de token. A implementação de exemplo usa uma classe base abstrata por meio da qual os consumidores de um determinado cache de token interagem com o cache.
public abstract class IssuedTokenCache { public abstract void AddToken ( GenericXmlSecurityToken token, EndpointAddress target, EndpointAddress issuer); public abstract bool TryGetToken(EndpointAddress target, EndpointAddress issuer, out GenericXmlSecurityToken cachedToken); } // Configure the client to use the custom client credential.Para o cliente usar a credencial de cliente personalizada, o exemplo exclui a classe de credencial de cliente padrão e fornece a nova classe de credencial de cliente.
clientFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); DurableIssuedTokenClientCredentials durableCreds = new DurableIssuedTokenClientCredentials(); durableCreds.IssuedTokenCache = cache; durableCreds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust; clientFactory.Endpoint.Behaviors.Add(durableCreds);
Executando o exemplo
Confira as instruções a seguir para executar o exemplo. Quando você executa o exemplo, a solicitação do token de segurança é mostrada na janela do console do Serviço de Token de Segurança. As solicitações e respostas da operação são exibidas nas janelas do cliente e do console de serviço. Pressione ENTER em qualquer uma das janelas do console para desligar o aplicativo.
O arquivo de lote Setup.cmd
O arquivo em lote Setup.cmd incluído com este exemplo permite que você configure o servidor e o serviço de token de segurança com os certificados relevantes para executar uma aplicação auto-hospedada. O arquivo em lote cria dois certificados no repositório de certificados CurrentUser/TrustedPeople. O primeiro certificado tem um nome de assunto de CN=STS e é usado pelo serviço de token de segurança para assinar os tokens de segurança que ele emite para o cliente. O segundo certificado tem um nome de assunto CN=localhost e é usado pelo Serviço de Token de Segurança para criptografar um segredo para que o serviço possa descriptografá-lo.
Para configurar, compilar e executar o exemplo
Execute o arquivo Setup.cmd para criar os certificados necessários.
Para compilar a solução, siga as instruções contidas em Como compilar as amostras do Windows Communication Foundation. Verifique se todos os projetos na solução foram criados (Shared, RSTRSTR, Service, SecurityTokenService e Client).
Verifique se Service.exe e SecurityTokenService.exe estão em execução com privilégios de administrador.
Execute Client.exe.
Para limpar após a amostra
Execute Cleanup.cmd na pasta de exemplos depois de concluir a execução do exemplo.