共用方式為


HOW TO:建立自訂安全性權杖提供者

這個主題會說明如何以自訂安全性權杖提供者建立新的權杖型別,以及如何整合提供者和自訂安全性權杖管理員。

ms734703.note(zh-tw,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 類別的執行個體,而這個執行個體適用於 WCF 安全性架構所傳遞至方法的 SecurityTokenRequirement 參數。使用適當的安全性權杖參數呼叫方法時,請修改方法以傳回自訂安全性權杖提供者實作 (在之前的程序中建立此實作)。如需安全性權杖管理員的詳細資訊,請參閱 逐步解說:建立自訂用戶端與服務認證

  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

概念

逐步解說:建立自訂用戶端與服務認證
HOW TO:建立自訂安全性權杖驗證器
安全性架構