チュートリアル: カスタム クライアントおよびサービスの資格情報を作成する
このトピックでは、クライアントおよびサービスにカスタム資格情報を実装する方法と、これをアプリケーション コードから使用する方法について説明します。
資格情報拡張クラス
ClientCredentials クラスおよび ServiceCredentials クラスは、Windows Communication Foundation (WCF) セキュリティ拡張のメイン エントリ ポイントです。これらの資格情報クラスでは、アプリケーション コードから資格情報を設定し、資格情報の種類をセキュリティ トークンに変換する API を提供します ("セキュリティ トークン" とは、SOAP メッセージ内の資格情報を送信するために使用される形式です)。これらの資格情報クラスの役割は、次の 2 つの領域に分けることができます。
アプリケーションで資格情報を設定するための API を提供します。
SecurityTokenManager 実装のファクトリとして動作します。
ClientCredentials クラスと ServiceCredentials クラスは、どちらも SecurityTokenManager を返すためのコントラクトを定義する SecurityCredentialsManager 抽象クラスから継承されます。
詳細情報 資格情報クラス、およびこれらのクラスが WCF のセキュリティ アーキテクチャに組み込まれるしくみの詳細については、「セキュリティ アーキテクチャ」を参照してください。
WCF で提供される既定の実装では、システム指定の資格情報の種類をサポートし、これらの資格情報の種類を処理できるセキュリティ トークン マネージャーを作成します。
カスタマイズする理由
クライアントまたはサービスの資格情報クラスをカスタマイズする場合、いくつかの理由があります。最大の理由として、システム指定の資格情報の種類の処理について、特に以下の必要性が生じたために WCF の既定のセキュリティ動作を変更する必要があることが挙げられます。
他の拡張ポイントを使用した場合には不可能な変更
新しい資格情報の種類の追加
新しいカスタム セキュリティ トークンの種類の追加
このトピックでは、カスタムのクライアント資格情報およびサービス資格情報を実装する方法と、これをアプリケーション コードから使用する方法について説明します。
最初の手順
資格情報をカスタマイズする理由は、資格情報の準備、セキュリティ トークンのシリアル化、または認証に関する WCF の動作を変更することにあるため、カスタム資格情報クラスの作成は最初の手順にすぎません。このセクションの他のトピックでは、カスタムのシリアライザーと認証システムを作成する方法について説明します。カスタム資格情報クラスの作成は、このような観点からすると、一連のトピックの最初の手順になります。これに続く処理 (カスタムのシリアライザーおよび認証システムの作成) は、カスタム資格情報の作成後にのみ可能になります。このトピックに基づく他のトピックには、次のものがあります。
手順
カスタム クライアント資格情報を実装するには
ClientCredentials クラスから派生する新しいクラスを定義します。
省略可能。新しい資格情報の種類に新しいメソッドまたはプロパティを追加します。新しい資格情報の種類を追加しない場合は、この手順を省略します。次の例では、
CreditCardNumber
プロパティを追加します。CreateSecurityTokenManager メソッドをオーバーライドします。カスタム クライアント資格情報が使用されると、WCF セキュリティ インフラストラクチャによってこのメソッドが自動的に呼び出されます。このメソッドは、SecurityTokenManager クラスの実装のインスタンスを作成して返す役割を担います。
注 : カスタム セキュリティ トークン マネージャーを作成するために、CreateSecurityTokenManager メソッドがオーバーライドされることに注意する必要があります。ClientCredentialsSecurityTokenManager から派生したセキュリティ トークン マネージャーは、実際のセキュリティ トークンを作成するために、SecurityTokenProvider から派生したカスタム セキュリティ トークン プロバイダーを返す必要があります。このパターンに従ってセキュリティ トークンを作成しないと、ChannelFactory オブジェクトがキャッシュされたとき (これは、WCF クライアント プロキシの既定の動作です)、権限の昇格攻撃を受ける可能性があり、アプリケーションが正常に機能しない場合があります。カスタム資格情報オブジェクトは、ChannelFactory の一部としてキャッシュされます。ただし、カスタム SecurityTokenManager がすべての呼び出し時に作成され、これにより、トークン作成ロジックが SecurityTokenManager にある限り、セキュリティの脅威が軽減されます。 CloneCore メソッドをオーバーライドします。
public class MyClientCredentials : ClientCredentials { string creditCardNumber; public MyClientCredentials() { // Perform client credentials initialization. } protected MyClientCredentials(MyClientCredentials other) : base(other) { // Clone fields defined in this class. this.creditCardNumber = other.creditCardNumber; } public string CreditCardNumber { get { return this.creditCardNumber; } set { if (value == null) { throw new ArgumentNullException("value"); } this.creditCardNumber = value; } } public override SecurityTokenManager CreateSecurityTokenManager() { // Return your implementation of the SecurityTokenManager. return new MyClientCredentialsSecurityTokenManager(this); } protected override ClientCredentials CloneCore() { // Implement the cloning functionality. return new MyClientCredentials(this); } }
カスタム クライアント セキュリティ トークン マネージャーを実装するには
ClientCredentialsSecurityTokenManager から派生する新しいクラスを定義します。
省略可能。カスタム SecurityTokenProvider 実装を作成する必要がある場合は、CreateSecurityTokenProvider メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークン プロバイダーについては、「方法 : カスタム セキュリティ トークン プロバイダーを作成する」を参照してください。
省略可能。カスタム SecurityTokenAuthenticator 実装を作成する必要がある場合は、CreateSecurityTokenAuthenticator メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークン認証システムについては、「方法 : カスタム セキュリティ トークン認証システムを作成する」を参照してください。
省略可能。カスタム SecurityTokenSerializer 実装を作成する必要がある場合は、CreateSecurityTokenSerializer メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークンおよびカスタム セキュリティ トークン シリアライザーについては、「方法 : カスタム トークンを作成する」を参照してください。
internal class MyClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager { MyClientCredentials credentials; public MyClientCredentialsSecurityTokenManager(MyClientCredentials credentials) : base(credentials) { this.credentials = credentials; } public override SecurityTokenProvider CreateSecurityTokenProvider( SecurityTokenRequirement tokenRequirement) { // Return your implementation of the SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenProvider(tokenRequirement); } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator( SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { // Return your implementation of the SecurityTokenAuthenticator, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { // Return your implementation of the SecurityTokenSerializer, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenSerializer(version); } }
アプリケーション コードによるカスタム クライアント資格情報を使用するには
サービス インターフェイスを表す、生成されたクライアントのインスタンスを作成するか、または通信の対象となるサービスを指す ChannelFactory のインスタンスを作成します。
Behaviors コレクションから、システム指定のクライアント資格情報の動作を削除します。このコレクションには、Endpoint プロパティからアクセスできます。
カスタム資格情報クラスの新しいインスタンスを作成し、Behaviors コレクションに追加します。このコレクションには、Endpoint プロパティからアクセスできます。
// Create a client with the client endpoint configuration. CalculatorClient client = new CalculatorClient(); // Remove the ClientCredentials behavior. client.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); // Add a custom client credentials instance to the behaviors collection. client.ChannelFactory.Endpoint.Behaviors.Add(new MyClientCredentials());
上記の手順は、アプリケーション コードからクライアント資格情報を使用する方法を示しています。WCF の資格情報は、アプリケーション構成ファイルを使用して構成することもできます。ソースの変更、再コンパイル、再展開を行うことなくアプリケーションのパラメーターを変更できるため、ハードコーディングを行うよりもアプリケーション構成ファイルの使用を一般にお勧めします。
次の手順では、カスタム資格情報の構成をサポートする方法について説明します。
カスタム クライアント資格情報の構成ハンドラーの作成
ClientCredentialsElement から派生する新しいクラスを定義します。
省略可能。アプリケーション構成を通じて公開する必要があるすべての追加構成パラメーターのプロパティを追加します。次の例では、
CreditCardNumber
という名前のプロパティを追加します。BehaviorType プロパティをオーバーライドして、構成要素によって作成されたカスタム クライアント資格情報クラスの型を返します。
CreateBehavior メソッドをオーバーライドします。このメソッドは、構成ファイルから読み込まれた設定に基づいてカスタム資格情報クラスのインスタンスを作成して返す役割を担います。このメソッドから ApplyConfiguration 基本メソッドを呼び出し、カスタム クライアント資格情報インスタンスに読み込まれたシステム指定の資格情報の設定を取得します。
省略可能。手順 2. で追加のプロパティを追加している場合は、Properties プロパティをオーバーライドして、追加した構成設定が構成フレームワークから認識されるよう登録します。追加したプロパティを基本クラスのプロパティと結合して、このカスタム クライアント資格情報の構成要素を通じてシステム指定の設定が構成されるようにします。
public class MyClientCredentialsConfigHandler : ClientCredentialsElement { ConfigurationPropertyCollection properties; public override Type BehaviorType { get { return typeof(MyClientCredentials); } } public string CreditCardNumber { get { return (string)base["creditCardNumber"]; } set { if (String.IsNullOrEmpty(value)) { value = String.Empty; } base["creditCardNumber"] = value; } } protected override ConfigurationPropertyCollection Properties { get { if (this.properties == null) { ConfigurationPropertyCollection properties = base.Properties; properties.Add(new ConfigurationProperty( "creditCardNumber", typeof(System.String), string.Empty, null, new StringValidator(0, 32, null), ConfigurationPropertyOptions.None)); this.properties = properties; } return this.properties; } } protected override object CreateBehavior() { MyClientCredentials creds = new MyClientCredentials(); creds.CreditCardNumber = CreditCardNumber; base.ApplyConfiguration(creds); return creds; } }
構成ハンドラー クラスを作成したら、WCF の構成フレームワークに統合できます。これにより、次の手順で示すように、カスタム クライアント資格情報をクライアント エンドポイント動作要素で使用できるようになります。
カスタム クライアント資格情報構成ハンドラーをアプリケーション構成に登録して使用するには
<extensions> 要素、および <behaviorExtensions> 要素を構成ファイルに追加します。
<add> 要素を <behaviorExtensions> 要素に追加し、name 属性を適切な値に設定します。
type 属性を完全修飾型名に設定します。また、アセンブリ名と他のアセンブリ属性を含めます。
<system.serviceModel> <extensions> <behaviorExtensions> <add name="myClientCredentials" type="Microsoft.ServiceModel.Samples.MyClientCredentialsConfigHandler, CustomCredentials, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> <system.serviceModel>
構成ハンドラーの登録後は、システム指定の <clientCredentials> 要素の代わりに、同じ構成ファイル内でカスタム資格情報要素を使用できます。システム指定のプロパティと、構成ハンドラーの実装に追加した任意の新規プロパティのどちらも使用できます。次の例では、creditCardNumber 属性を使用して、カスタム プロパティの値を設定します。
<behaviors> <endpointBehaviors> <behavior name="myClientCredentialsBehavior"> <myClientCredentials creditCardNumber="123-123-123"/> </behavior> </endpointBehaviors> </behaviors>
カスタム サービス資格情報を実装するには
ServiceCredentials から派生する新しいクラスを定義します。
省略可能。追加している新しい資格情報の値に API を提供するために新しいプロパティを追加します。新しい資格情報の値を追加しない場合は、この手順を省略します。次の例では、
AdditionalCertificate
プロパティを追加します。CreateSecurityTokenManager メソッドをオーバーライドします。カスタム クライアント資格情報が使用されると、WCF インフラストラクチャによって、このメソッドが自動的に呼び出されます。このメソッドは、SecurityTokenManager クラスの実装のインスタンスを作成して返す役割を担います (次の手順で説明)。
省略可能。CloneCore メソッドをオーバーライドします。この手順は、カスタム クライアント資格情報の実装に新しいプロパティまたは内部フィールドを追加する場合にのみ必要になります。
public class MyServiceCredentials : ServiceCredentials { X509Certificate2 additionalCertificate; public MyServiceCredentials() { } protected MyServiceCredentials(MyServiceCredentials other) : base(other) { this.additionalCertificate = other.additionalCertificate; } public X509Certificate2 AdditionalCertificate { get { return this.additionalCertificate; } set { if (value == null) { throw new ArgumentNullException("value"); } this.additionalCertificate = value; } } public override SecurityTokenManager CreateSecurityTokenManager() { return base.CreateSecurityTokenManager(); } protected override ServiceCredentials CloneCore() { return new MyServiceCredentials(this); } }
カスタム サービス セキュリティ トークン マネージャーを実装するには
ServiceCredentialsSecurityTokenManager クラスから派生する新しいクラスを定義します。
省略可能。カスタム SecurityTokenProvider 実装を作成する必要がある場合は、CreateSecurityTokenProvider メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークン プロバイダーについては、「方法 : カスタム セキュリティ トークン プロバイダーを作成する」を参照してください。
省略可能。カスタム SecurityTokenAuthenticator 実装を作成する必要がある場合は、CreateSecurityTokenAuthenticator メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークン認証システムについては、「方法 : カスタム セキュリティ トークン認証システムを作成する」を参照してください。
省略可能。カスタム SecurityTokenSerializer 実装を作成する必要がある場合は、CreateSecurityTokenSerializer メソッドをオーバーライドします。詳細情報 カスタム セキュリティ トークンおよびカスタム セキュリティ トークン シリアライザーについては、「方法 : カスタム トークンを作成する」を参照してください。
internal class MyServiceCredentialsSecurityTokenManager : ServiceCredentialsSecurityTokenManager { MyServiceCredentials credentials; public MyServiceCredentialsSecurityTokenManager(MyServiceCredentials credentials) : base(credentials) { this.credentials = credentials; } public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenProvider(tokenRequirement); } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenSerializer(version); } }
アプリケーション コードによるカスタム サービス資格情報を使用するには
ServiceHost のインスタンスを作成します。
Behaviors コレクションから、システム指定のサービス資格情報の動作を削除します。
カスタム サービス資格情報クラスの新しいインスタンスを作成し、これを Behaviors コレクションに追加します。
// Create a service host with a service type. ServiceHost serviceHost = new ServiceHost(typeof(Service)); // Remove the default ServiceCredentials behavior. serviceHost.Description.Behaviors.Remove<ServiceCredentials>(); // Add a custom service credentials instance to the collection. serviceHost.Description.Behaviors.Add(new MyServiceCredentials());
前の「To create a configuration handler for custom client credentials」および「To register and use a custom client credentials configuration handler in the application configuration」で説明した手順を使用して構成にサポートを追加します。構成ハンドラーの基本クラスとして、ClientCredentialsElement クラスではなく ServiceCredentialsElement クラスを使用する点のみが異なります。カスタム サービス資格情報要素は、システム指定の <serviceCredentials>
要素を使用する場合にいつでも使用できます。
参照
処理手順
方法 : カスタム セキュリティ トークン プロバイダーを作成する
リファレンス
ClientCredentials
ServiceCredentials
SecurityCredentialsManager
SecurityTokenManager
ClientCredentialsElement
ServiceCredentialsElement