Compartir vía


Procedimiento para crear un proveedor de tokens de seguridad personalizado

En este tema se muestra cómo crear nuevos tipos de token con un proveedor de tokens de seguridad personalizado y cómo integrar el proveedor con un administrador de tokens de seguridad personalizado.

Nota

Cree un proveedor de tokens personalizado si los tokens proporcionados por el sistema ubicados en el espacio de nombres System.IdentityModel.Tokens no coinciden con sus requisitos.

El proveedor de tokens de seguridad crea una representación de token de seguridad basada en información en el cliente o en las credenciales de servicio. Para usar el proveedor de tokens de seguridad personalizados en Windows Communication Foundation (WCF), debe crear implementaciones personalizadas del administrador de credenciales y tokens de seguridad.

Para más información sobre el administrador de credenciales y tokens de seguridad, consulte el Tutorial: Creación de credenciales de cliente y servicio personalizadas.

Para crear un proveedor de tokens de seguridad personalizado

  1. Defina una clase nueva derivada de la clase SecurityTokenProvider.

  2. Implemente el método GetTokenCore(TimeSpan). El método es responsable de crear y devolver una instancia del token de seguridad. El ejemplo siguiente crea una clase denominada MySecurityTokenProvidere invalida el método GetTokenCore(TimeSpan) para devolver una instancia de la clase X509SecurityToken. El constructor de clase necesita una instancia de la clase 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 un proveedor de tokens de seguridad personalizado con un administrador de tokens de seguridad personalizado

  1. Defina una clase nueva derivada de la clase SecurityTokenManager. (El siguiente ejemplo se deriva de la clase ClientCredentialsSecurityTokenManager, que se deriva de la clase SecurityTokenManager).

  2. Si no está ya invalidado, invalide el método CreateSecurityTokenProvider(SecurityTokenRequirement).

    El método CreateSecurityTokenProvider(SecurityTokenRequirement) es responsable de devolver una instancia de la clase SecurityTokenProvider adecuada al parámetro SecurityTokenRequirement que el marco de seguridad WCF pasó al método. Modifique el método para devolver la implementación de proveedor de tokens de seguridad personalizado (creada en el procedimiento anterior) cuando se llama al método con un parámetro de token de seguridad adecuado. Para más información sobre el administrador de tokens de seguridad, consulte el Tutorial: Creación de credenciales de cliente y servicio personalizadas.

  3. Agregue la lógica personalizada al método para permitirle que devuelva su proveedor de tokens de seguridad personalizado basado en el parámetro SecurityTokenRequirement. El ejemplo siguiente devuelve el proveedor de tokens de seguridad personalizado si se cumplen los requisitos del token. Los requisitos incluyen un token de seguridad X.509 y la dirección del mensaje (que el token se utiliza para la salida del mensaje). Para todos los casos restantes, el código llama a la clase base para mantener el comportamiento proporcionado por el sistema para otros requisitos de token de seguridad.

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

Ejemplo

A continuación se presenta una implementación SecurityTokenProvider completa junto con una implementación SecurityTokenManager correspondiente.

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

Consulte también