Vorgehensweise: Erstellen eines benutzerdefinierten Sicherheitstokenanbieters

In diesem Thema wird beschrieben, wie Sie neue Tokentypen mit einem benutzerdefinierten Sicherheitstokenanbieter erstellen und den Anbieter in einen benutzerdefinierten Sicherheitstoken-Manager integrieren.

Hinweis

Erstellen Sie einen benutzerdefinierten Tokenanbieter, wenn die im System.IdentityModel.Tokens-Namespace gefundenen vom System bereitgestellten Token Ihren Anforderungen nicht entsprechen.

Der Sicherheitstokenanbieter erstellt eine Sicherheitstokendarstellung basierend auf Daten in den Client- oder Dienstanmeldeinformationen. Um den benutzerdefinierten Sicherheitstokenanbieter in Windows Communication Foundation (WCF)-Sicherheit zu verwenden, müssen Sie benutzerdefinierte Anmeldeinformationen und Sicherheitstoken-Managerimplementierungen erstellen.

Weitere Informationen über benutzerdefinierte Anmeldeinformationen und Sicherheitstoken-Manager finden Sie unter Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen.

Weitere Informationen über Anmeldeinformationen, Sicherheitstoken-Manager sowie Anbieter- und Authentifiziererklassen finden Sie unter Security Architecture.

So erstellen Sie einen benutzerdefinierten Sicherheitstokenanbieter

  1. Definieren Sie eine neue von der SecurityTokenProvider-Klasse abgeleitete Klasse.

  2. Implementieren Sie die GetTokenCore(TimeSpan)-Methode. Die Methode ist für die Erstellung und die Rückgabe einer Instanz des Sicherheitstokens verantwortlich. Im folgenden Beispiel wird eine Klasse mit der Bezeichnung MySecurityTokenProvider erstellt und die GetTokenCore(TimeSpan)-Methode überschrieben, um eine Instanz der X509SecurityToken-Klasse zurückzugeben. Der Klassenkonstruktor erfordert eine neue Instanz der X509Certificate2-Klasse.

    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 
    

So integrieren Sie einen benutzerdefinierten Sicherheitstokenanbieter in einen benutzerdefinierten Sicherheitstoken-Manager

  1. Definieren Sie eine neue von der SecurityTokenManager-Klasse abgeleitete Klasse. (Das nachfolgende Beispiel ist von der ClientCredentialsSecurityTokenManager-Klasse abgeleitet, die von der SecurityTokenManager-Klasse abgeleitet ist.)

  2. Überschreiben Sie die CreateSecurityTokenProvider(SecurityTokenRequirement)-Methode, wenn sie noch nicht überschrieben ist.

    Die CreateSecurityTokenProvider(SecurityTokenRequirement)-Methode ist für die Rückgabe einer Instanz der SecurityTokenProvider-Klasse verantwortlich, entsprechend dem SecurityTokenRequirement-Parameter, der an die Methode vom WCF-Sicherheitsframework übergeben wurde. Ändern Sie die Methode zur Rückgabe der Implementierung des benutzerdefinierten Sicherheitstokenanbieters (die mit dem vorherigen Verfahren erstellt wurde), wenn die Methode mit einem entsprechenden Sicherheitstokenparameter aufgerufen wird. Weitere Informationen zum Sicherheitstoken-Manager finden Sie unter Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen.

  3. Fügen Sie benutzerdefinierte Logik zur Methode hinzu, um diese zu befähigen, den benutzerdefinierten Sicherheitstokenanbieter basierend auf dem SecurityTokenRequirement-Parameter zurückzugeben. Im folgenden Beispiel wird der benutzerdefinierte Sicherheitstokenanbieter zurückgegeben, wenn die Tokenanforderungen erfüllt werden. Die Anforderungen umfassen ein X.509-Sicherheitstoken und die Nachrichtenrichtung (die das Token für die Nachrichtenausgabe verwendet). In allen anderen Fällen ruft der Code die Basisklasse ab, um das vom System bereitgestellte Verhalten für andere Sicherheitstokenanforderungen zu verwalten.

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 'New
    
    
    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 

Beispiel

Im Folgenden wird eine vollständige SecurityTokenProvider-Implementierung zusammen mit einer entsprechenden SecurityTokenManager-Implementierung gezeigt.

using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Permissions;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security.Tokens;

[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
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
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

<assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution := True)>
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 'New
    
    
    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 

Siehe auch

SecurityTokenProvider
SecurityTokenRequirement
SecurityTokenManager
X509SecurityToken
Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen
Vorgehensweise: Erstellen eines benutzerdefinierten Sicherheitstokenauthentifizierers
Security Architecture