Como: criar um provedor de token de segurança personalizado
Este tópico mostra como criar novos tipos de token com um provedor de token de segurança personalizado e como integrar o provedor a um gerenciador de tokens de segurança personalizado.
Observação
Crie um provedor de token personalizado se os tokens fornecidos pelo sistema encontrados no namespace System.IdentityModel.Tokens não corresponderem aos seus requisitos.
O provedor de token de segurança cria uma representação de token de segurança com base nas informações das credenciais de cliente ou serviço. Para usar o provedor de token de segurança personalizado na segurança do WCF (Windows Communication Foundation), você deve criar credenciais personalizadas e implementações do gerenciador de tokens de segurança.
Para obter mais informações sobre credenciais personalizadas e um gerenciador de token de segurança, consulte o Passo a passo: Criar credenciais personalizadas de cliente e serviço.
Para criar um provedor de token de segurança personalizado
Defina uma nova classe derivada da classe SecurityTokenProvider.
Implementar o método de GetTokenCore(TimeSpan) . O método é responsável por criar e retornar uma instância do token de segurança. O exemplo a seguir cria uma classe chamada
MySecurityTokenProvider
e substitui o método GetTokenCore(TimeSpan) para retornar uma instância da classe X509SecurityToken. O construtor de classe requer uma instância da classe X509Certificate2.internal class MySecurityTokenProvider : SecurityTokenProvider { X509Certificate2 certificate; public MySecurityTokenProvider(X509Certificate2 certificate) { this.certificate = certificate; } protected override SecurityToken GetTokenCore(TimeSpan timeout) { return new X509SecurityToken(certificate); } }
Friend Class MySecurityTokenProvider Inherits SecurityTokenProvider Private certificate As X509Certificate2 Public Sub New(ByVal certificate As X509Certificate2) Me.certificate = certificate End Sub Protected Overrides Function GetTokenCore(ByVal timeout As TimeSpan) As SecurityToken Return New X509SecurityToken(certificate) End Function End Class
Para integrar um provedor de token de segurança personalizado a um gerenciador de tokens de segurança personalizado
Defina uma nova classe derivada da classe SecurityTokenManager. (O exemplo a seguir deriva da classe ClientCredentialsSecurityTokenManager, que deriva da classe SecurityTokenManager).
Substitua o método CreateSecurityTokenProvider(SecurityTokenRequirement) se ainda não estiver substituído.
O método CreateSecurityTokenProvider(SecurityTokenRequirement) é responsável por retornar uma instância da classe SecurityTokenProvider apropriada ao parâmetro SecurityTokenRequirement passado para o método pela estrutura de segurança do WCF. Modifique o método para retornar a implementação do provedor de token de segurança personalizado (criado no procedimento anterior) quando o método for chamado com um parâmetro de token de segurança apropriado. Para obter mais informações sobre o gerenciador de tokens de segurança, consulte o Passo a passo: criar credenciais de cliente e serviço personalizadas.
Adicione lógica personalizada ao método para permitir que ele retorne seu provedor de token de segurança personalizado com base no parâmetro SecurityTokenRequirement. O exemplo a seguir retorna o provedor de token de segurança personalizado se os requisitos de token forem atendidos. Os requisitos incluem um token de segurança X.509 e a direção da mensagem (que o token é usado para a saída da mensagem). Para todos os outros casos, o código chama a classe base para manter o comportamento fornecido pelo sistema para outros requisitos de token de segurança.
internal class MyClientCredentialsSecurityTokenManager:ClientCredentialsSecurityTokenManager
{
ClientCredentials credentials;
public MyClientCredentialsSecurityTokenManager(ClientCredentials credentials)
: base(credentials)
{
this.credentials = credentials;
}
public override SecurityTokenProvider CreateSecurityTokenProvider(
SecurityTokenRequirement tokenRequirement)
{
// Return your implementation of the SecurityTokenProvider based on the
// tokenRequirement argument.
SecurityTokenProvider result;
if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
{
MessageDirection direction = tokenRequirement.GetProperty<MessageDirection>(
ServiceModelSecurityTokenRequirement.MessageDirectionProperty);
if (direction == MessageDirection.Output)
{
result = new MySecurityTokenProvider(credentials.ClientCertificate.Certificate);
}
else
{
result = base.CreateSecurityTokenProvider(tokenRequirement);
}
}
else
{
result = base.CreateSecurityTokenProvider(tokenRequirement);
}
return result;
}
}
Friend Class MyClientCredentialsSecurityTokenManager
Inherits ClientCredentialsSecurityTokenManager
Private credentials As ClientCredentials
Public Sub New(ByVal credentials As ClientCredentials)
MyBase.New(credentials)
Me.credentials = credentials
End Sub
Public Overrides Function CreateSecurityTokenProvider(ByVal tokenRequirement As SecurityTokenRequirement) As SecurityTokenProvider
' Return your implementation of the SecurityTokenProvider based on the
' tokenRequirement argument.
Dim result As SecurityTokenProvider
If tokenRequirement.TokenType = SecurityTokenTypes.X509Certificate Then
Dim direction As MessageDirection = tokenRequirement.GetProperty(Of MessageDirection) _
(ServiceModelSecurityTokenRequirement.MessageDirectionProperty)
If direction = MessageDirection.Output Then
result = New MySecurityTokenProvider(credentials.ClientCertificate.Certificate)
Else
result = MyBase.CreateSecurityTokenProvider(tokenRequirement)
End If
Else
result = MyBase.CreateSecurityTokenProvider(tokenRequirement)
End If
Return result
End Function
End Class
Exemplo
O exemplo a seguir mostra uma implementação completa de SecurityTokenProvider junto com uma implementação correspondente de SecurityTokenManager.
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security.Tokens;
namespace CustomProvider
{
internal class MySecurityTokenProvider : SecurityTokenProvider
{
X509Certificate2 certificate;
public MySecurityTokenProvider(X509Certificate2 certificate)
{
this.certificate = certificate;
}
protected override SecurityToken GetTokenCore(TimeSpan timeout)
{
return new X509SecurityToken(certificate);
}
}
internal class MyClientCredentialsSecurityTokenManager:ClientCredentialsSecurityTokenManager
{
ClientCredentials credentials;
public MyClientCredentialsSecurityTokenManager(ClientCredentials credentials)
: base(credentials)
{
this.credentials = credentials;
}
public override SecurityTokenProvider CreateSecurityTokenProvider(
SecurityTokenRequirement tokenRequirement)
{
// Return your implementation of the SecurityTokenProvider based on the
// tokenRequirement argument.
SecurityTokenProvider result;
if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
{
MessageDirection direction = tokenRequirement.GetProperty<MessageDirection>(
ServiceModelSecurityTokenRequirement.MessageDirectionProperty);
if (direction == MessageDirection.Output)
{
result = new MySecurityTokenProvider(credentials.ClientCertificate.Certificate);
}
else
{
result = base.CreateSecurityTokenProvider(tokenRequirement);
}
}
else
{
result = base.CreateSecurityTokenProvider(tokenRequirement);
}
return result;
}
}
}
Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens
Imports System.Security.Permissions
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Security.Tokens
Friend Class MySecurityTokenProvider
Inherits SecurityTokenProvider
Private certificate As X509Certificate2
Public Sub New(ByVal certificate As X509Certificate2)
Me.certificate = certificate
End Sub
Protected Overrides Function GetTokenCore(ByVal timeout As TimeSpan) As SecurityToken
Return New X509SecurityToken(certificate)
End Function
End Class
Friend Class MyClientCredentialsSecurityTokenManager
Inherits ClientCredentialsSecurityTokenManager
Private credentials As ClientCredentials
Public Sub New(ByVal credentials As ClientCredentials)
MyBase.New(credentials)
Me.credentials = credentials
End Sub
Public Overrides Function CreateSecurityTokenProvider(ByVal tokenRequirement As SecurityTokenRequirement) As SecurityTokenProvider
' Return your implementation of the SecurityTokenProvider based on the
' tokenRequirement argument.
Dim result As SecurityTokenProvider
If tokenRequirement.TokenType = SecurityTokenTypes.X509Certificate Then
Dim direction As MessageDirection = tokenRequirement.GetProperty(Of MessageDirection) _
(ServiceModelSecurityTokenRequirement.MessageDirectionProperty)
If direction = MessageDirection.Output Then
result = New MySecurityTokenProvider(credentials.ClientCertificate.Certificate)
Else
result = MyBase.CreateSecurityTokenProvider(tokenRequirement)
End If
Else
result = MyBase.CreateSecurityTokenProvider(tokenRequirement)
End If
Return result
End Function
End Class