HOW TO:建立自訂安全性權杖提供者
這個主題會說明如何以自訂安全性權杖提供者建立新的權杖型別,以及如何整合提供者和自訂安全性權杖管理員。
注意: |
---|
如果在 System.IdentityModel.Tokens 命名空間中,所找到的系統提供之權杖不符合您的需求,請建立自訂權杖提供者。 |
安全性權杖提供者會根據用戶端或服務認證中的資訊,建立安全性權杖表示。若要在 Windows Communication Foundation (WCF) 安全性中使用自訂安全性權杖提供者,您必須建立自訂認證和安全性權杖管理員實作。
如需自訂認證和安全性權杖管理員的詳細資訊,請參閱 逐步解說:建立自訂用戶端與服務認證。
如需認證、安全性權杖管理員、提供者和驗證器類別的詳細資訊,請參閱安全性架構。
建立自訂安全性權杖提供者
定義衍生自 SecurityTokenProvider 類別的新類別。
實作 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); } }
整合自訂安全性權杖提供者和自訂安全性權杖管理員
定義衍生自 SecurityTokenManager 類別的新類別 (以下範例衍生自 ClientCredentialsSecurityTokenManager 類別,而這個類別則衍生自 SecurityTokenManager 類別)。
如果尚未覆寫 CreateSecurityTokenProvider 方法,請覆寫之。
CreateSecurityTokenProvider 方法會負責傳回 SecurityTokenProvider 類別的執行個體,而這個執行個體適用於 WCF 安全性架構所傳遞至方法的 SecurityTokenRequirement 參數。使用適當的安全性權杖參數呼叫方法時,請修改方法以傳回自訂安全性權杖提供者實作 (在之前的程序中建立此實作)。如需安全性權杖管理員的詳細資訊,請參閱 逐步解說:建立自訂用戶端與服務認證。
將自訂邏輯新增至方法,讓方法可以根據 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