Udostępnij za pośrednictwem


Instrukcje: tworzenie niestandardowego dostawcy tokenów zabezpieczeń

W tym temacie pokazano, jak utworzyć nowe typy tokenów z niestandardowym dostawcą tokenów zabezpieczających oraz jak zintegrować dostawcę z niestandardowym menedżerem tokenów zabezpieczających.

Uwaga

Utwórz niestandardowego dostawcę tokenu, jeśli tokeny dostarczone przez system znajdujące się w System.IdentityModel.Tokens przestrzeni nazw nie są zgodne z wymaganiami.

Dostawca tokenu zabezpieczającego tworzy reprezentację tokenu zabezpieczającego na podstawie informacji w poświadczeniach klienta lub usługi. Aby użyć niestandardowego dostawcy tokenów zabezpieczających w zabezpieczeniach programu Windows Communication Foundation (WCF), należy utworzyć niestandardowe poświadczenia i implementacje menedżera tokenów zabezpieczających.

Aby uzyskać więcej informacji na temat niestandardowych poświadczeń i menedżera tokenów zabezpieczających, zobacz Przewodnik: tworzenie niestandardowych poświadczeń klienta i usługi.

Aby utworzyć niestandardowego dostawcę tokenu zabezpieczającego

  1. Zdefiniuj nową klasę pochodzącą SecurityTokenProvider z klasy .

  2. Zaimplementuj metodę GetTokenCore(TimeSpan) . Metoda jest odpowiedzialna za tworzenie i zwracanie wystąpienia tokenu zabezpieczającego. Poniższy przykład tworzy klasę o nazwie MySecurityTokenProvideri zastępuje GetTokenCore(TimeSpan) metodę w celu zwrócenia wystąpienia X509SecurityToken klasy. Konstruktor klasy wymaga wystąpienia X509Certificate2 klasy.

    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
    

Aby zintegrować niestandardowego dostawcę tokenów zabezpieczających z niestandardowym menedżerem tokenów zabezpieczających

  1. Zdefiniuj nową klasę pochodzącą SecurityTokenManager z klasy . (Poniższy przykład pochodzi z ClientCredentialsSecurityTokenManager klasy, która pochodzi z SecurityTokenManager klasy ).

  2. Zastąpij metodę CreateSecurityTokenProvider(SecurityTokenRequirement) , jeśli jeszcze nie zostanie zastąpiona.

    Metoda CreateSecurityTokenProvider(SecurityTokenRequirement) jest odpowiedzialna za zwrócenie wystąpienia SecurityTokenProvider klasy odpowiedniej dla SecurityTokenRequirement parametru przekazanego do metody przez platformę zabezpieczeń WCF. Zmodyfikuj metodę, aby zwrócić niestandardową implementację dostawcy tokenów zabezpieczających (utworzoną w poprzedniej procedurze), gdy metoda jest wywoływana przy użyciu odpowiedniego parametru tokenu zabezpieczającego. Aby uzyskać więcej informacji na temat menedżera tokenów zabezpieczeń, zobacz Przewodnik: tworzenie niestandardowych poświadczeń klienta i usługi.

  3. Dodaj logikę niestandardową do metody , aby umożliwić jej zwrócenie niestandardowego dostawcy tokenów zabezpieczających na podstawie parametru SecurityTokenRequirement . Poniższy przykład zwraca niestandardowego dostawcę tokenu zabezpieczającego, jeśli są spełnione wymagania dotyczące tokenu. Wymagania obejmują token zabezpieczający X.509 i kierunek komunikatu (że token jest używany na potrzeby danych wyjściowych komunikatów). W przypadku wszystkich innych przypadków kod wywołuje klasę bazową, aby zachować zachowanie dostarczone przez system dla innych wymagań dotyczących tokenów zabezpieczających.

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

Przykład

Poniżej przedstawiono kompletną SecurityTokenProvider implementację wraz z odpowiednią SecurityTokenManager implementacją.

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

Zobacz też