作法:建立自訂安全性權杖提供者
這個主題會說明如何以自訂安全性權杖提供者建立新的權杖型別,以及如何整合提供者和自訂安全性權杖管理員。
注意
如果在 System.IdentityModel.Tokens 命名空間中,所找到的系統提供之權杖不符合您的需求,請建立自訂權杖提供者。
安全性權杖提供者會根據用戶端或服務認證中的資訊,建立安全性權杖表示。 若要在 Windows Communication Foundation (WCF) 中使用自訂安全性權杖提供者,您必須建立自訂認證和安全性權杖管理員實作。
如需自訂認證和安全性權杖管理員的詳細資訊,請參閱逐步解說:建立自訂用戶端與服務認證。
建立自訂安全性權杖提供者
定義衍生自 SecurityTokenProvider 類別的新類別。
實作 GetTokenCore(TimeSpan) 方法。 這個方法會負責建立和傳回安全性權杖的執行個體。 下列範例會建立名稱為
MySecurityTokenProvider
的類別,並覆寫 GetTokenCore(TimeSpan) 方法以傳回 X509SecurityToken 類別的執行個體。 類別建構函式需要 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
整合自訂安全性權杖提供者和自訂安全性權杖管理員
定義衍生自 SecurityTokenManager 類別的新類別。 (以下範例衍生自 ClientCredentialsSecurityTokenManager 類別,而這個類別則衍生自 SecurityTokenManager 類別)。
如果尚未覆寫 CreateSecurityTokenProvider(SecurityTokenRequirement) 方法,請覆寫之。
CreateSecurityTokenProvider(SecurityTokenRequirement) 方法會負責根據 WCF 安全性架構傳遞至方法的 SecurityTokenRequirement 參數,傳回適當的 SecurityTokenProvider 類別執行個體。 使用適當的安全性權杖參數呼叫方法時,請修改方法以傳回自訂安全性權杖提供者實作 (在之前的程序中建立此實作)。 如需安全性權杖管理員的詳細資訊,請參閱逐步解說:建立自訂用戶端與服務認證。
將自訂邏輯新增至方法,讓方法可以根據 SecurityTokenRequirement 參數傳回自訂安全性權杖提供者。 下列範例會在符合權杖需求時,傳回自訂安全性權杖提供者。 這些需求包括 X.509 安全性權杖和訊息方向 (當權杖用於訊息輸出時)。 在其他情況下,程式碼會呼叫基底類別,以針對其他安全性權杖需求維護系統提供的行為。
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
範例
下列範例會顯示完整 SecurityTokenProvider 實作以及相對應的 SecurityTokenManager 實作。
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