Поделиться через


Как создать пользовательский поставщик маркеров безопасности

В этом разделе показано, как создавать новые типы маркеров с помощью поставщика пользовательских маркеров безопасности и как интегрировать поставщик с диспетчером пользовательских маркеров безопасности.

ms734703.note(ru-ru,VS.100).gifПримечание
Поставщик пользовательских маркеров следует создавать, если предоставляемые системой маркеры в пространстве имен System.IdentityModel.Tokens не соответствуют требованиям.

Поставщик маркеров безопасности создает представление маркера безопасности на основании сведений в учетных данных клиента или службы. Чтобы использовать пользовательский поставщик проверки подлинности в Windows Communication Foundation (WCF), необходимо создать пользовательские реализации учетных данных и диспетчера маркеров безопасности.

Дополнительные сведения о пользовательских учетных данных и диспетчере маркеров безопасности см. в разделе Пошаговое руководство. Создание пользовательских учетных данных для клиента и службы.

Дополнительные сведения о классах учетных данных, диспетчера маркеров безопасности, а также поставщика и структуры проверки подлинности см. в разделе Архитектура безопасности.

Создание поставщика пользовательских маркеров безопасности

  1. Определите новый класс, наследуемый от класса SecurityTokenProvider.

  2. Реализуйте метод GetTokenCore. Этот метод отвечает за создание и возвращение экземпляра маркера безопасности. В следующем примере создается класс с именем MySecurityTokenProvider и переопределяется метод GetTokenCore, чтобы он возвращал экземпляр класса X509SecurityToken. Конструктору класса требуется экземпляр класса X509Certificate2.

    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 
    
    internal class MySecurityTokenProvider : SecurityTokenProvider
    {
        X509Certificate2 certificate;
    
        public MySecurityTokenProvider(X509Certificate2 certificate)
        {
            this.certificate = certificate;
        }
    
        protected override SecurityToken GetTokenCore(TimeSpan timeout)
        {
            return new X509SecurityToken(certificate);
        }
    }
    

Интеграция поставщика пользовательских маркеров безопасности с диспетчером пользовательских маркеров безопасности

  1. Определите новый класс, наследуемый от класса SecurityTokenManager. (В следующем примере кода создается класс ClientCredentialsSecurityTokenManager, наследуемый от класса SecurityTokenManager.)

  2. Переопределите метод CreateSecurityTokenProvider, если он еще не переопределен.

    Метод CreateSecurityTokenProvider отвечает за возврат экземпляра класса SecurityTokenProvider в соответствии с параметром SecurityTokenRequirement, переданным методу средой безопасности WCF. Измените метод, чтобы он возвращал реализацию поставщика пользовательских маркеров безопасности (созданную перед этим), когда этот метод вызывается с соответствующим параметром маркера безопасности. Дополнительные сведения о диспетчере маркеров безопасности см. в разделе Пошаговое руководство. Создание пользовательских учетных данных для клиента и службы.

  3. Добавьте в метод соответствующие инструкции, чтобы он мог возвращать поставщик пользовательских маркеров безопасности на основании параметра SecurityTokenRequirement. В следующем примере метод возвращает поставщик пользовательских маркеров безопасности, если выполняются требования маркера. Требования включают маркер безопасности X.509 и направление сообщения (маркер используется для вывода сообщений). Во всех остальных случаях код вызывает базовый класс для поддержки предоставляемого системой поведения для требований других маркеров безопасности.

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 
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;
    }
}

Пример

Ниже показана полная реализация поставщика SecurityTokenProvider, а также соответствующая реализация диспетчера SecurityTokenManager.

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 
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;
        }
    }
}

См. также

Справочник

SecurityTokenProvider
SecurityTokenRequirement
SecurityTokenManager
X509SecurityToken

Основные понятия

Пошаговое руководство. Создание пользовательских учетных данных для клиента и службы
Как создавать пользовательскую структуру проверки подлинности маркера безопасности
Архитектура безопасности