方法: セキュリティで保護されたセッションに対しセキュリティ コンテキスト トークンを作成する
セキュリティで保護されたセッションでステートフルなセキュリティ コンテキスト トークン (SCT: Security Context Token) を使用すると、そのセッションでサービスを再利用できます。 たとえば、セキュリティで保護されたセッションでステートレスな SCT を使用しているときにインターネット インフォメーション サービス (IIS) をリセットすると、サービスに関連付けられているセッション データが失われます。 このセッション データには、SCT キャッシュが含まれています。 このため、クライアントが次回ステートレスな SCT をサービスに送信すると、エラーが返されます。これは、SCT に関連付けられているキーを取得できないためです。 しかし、ステートフルな SCT を使用した場合、SCT に関連付けられているキーは、その SCT 内に格納されます。 キーが SCT 内、つまりメッセージ内に格納されているため、セキュリティで保護されたセッションは、サービスの再使用の影響を受けません。 既定では、Windows Communication Foundation (WCF) は、セキュリティで保護されたセッションでステートレスな SCT を使用します。 ここでは、セキュリティで保護されたセッションでステートフルな SCT を使用する方法について詳しく説明します。
Note
IDuplexChannel から派生したコントラクトに関係する、セキュリティで保護されたセッションでは、ステートフルな SCT を使用できません。
Note
セキュリティで保護されたセッションでステートフルな SCT を使用するアプリケーションでは、サービスのスレッド ID は、関連付けられたユーザー プロファイルを持つユーザー アカウントである必要があります。 ユーザー プロファイルを持たないアカウント (Local Service
など) でサービスを実行すると、例外がスローされる場合があります。
Note
Windows XP で偽装が必要な場合は、ステートフルな SCT を使用しない、セキュリティで保護されたセッションを使用します。 ステートフル SCT が偽装と共に使用されると、InvalidOperationException がスローされます。 詳細については、「サポートされていないシナリオ」を参照してください。
セキュリティで保護されたセッションでステートフルな SCT を使用するには
ステートフルな SCT を使用する、セキュリティで保護されたセッションによって SOAP メッセージを保護するように指定するカスタム バインディングを作成します。
サービスの構成ファイルに <customBinding> を追加して、カスタム バインディングを定義します。
<customBinding> </customBinding>
<customBinding> に <binding> 子要素を追加します。
name
属性を、構成ファイル内で一意の名前に設定してバンディング名を指定します。<binding name="StatefulSCTSecureSession"> </binding>
<customBinding> に <security> 子要素を追加して、このサービスとの間で送受信されるメッセージの認証モードを指定します。
authenticationMode
属性をSecureConversation
に設定して、セキュリティで保護されたセッションを指定します。requireSecurityContextCancellation
属性をfalse
に設定して、ステートフルな SCT を使用するように指定します。<security authenticationMode="SecureConversation" requireSecurityContextCancellation="false"> </security>
<security> に <secureConversationBootstrap> 子要素を追加して、セキュリティで保護されたセッションが確立されているときにクライアントを認証する方法を指定します。
クライアントの認証方法は、
authenticationMode
属性を設定して指定します。<secureConversationBootstrap authenticationMode="UserNameForCertificate" />
<textMessageEncoding> などのエンコード要素を追加して、メッセージ エンコードを指定します。
<textMessageEncoding />
<httpTransport> などのトランスポート要素を追加して、トランスポートを指定します。
<httpTransport />
次のコード例では、構成を使用して、セキュリティで保護されたセッションでメッセージがステートフルな SCT と共に使用できるカスタム バインディングを指定します。
<customBinding> <binding name="StatefulSCTSecureSession"> <security authenticationMode="SecureConversation" requireSecurityContextCancellation="false"> <secureConversationBootstrap authenticationMode="UserNameForCertificate" /> </security> <textMessageEncoding /> <httpTransport /> </binding> </customBinding>
例
セキュリティで保護されたセッションをブートストラップするための MutualCertificate 認証モードを使用する、カスタム バインドを作成するコード例を次に示します。
SecurityBindingElement security = SecurityBindingElement.CreateMutualCertificateBindingElement();
// Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, false);
// Specify whether derived keys are needed.
security.SetKeyDerivation(true);
// Create the custom binding.
CustomBinding myBinding = new CustomBinding(security, new HttpTransportBindingElement());
// Create the Type instances for later use and the Uri for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
Uri("http://localhost:8036/serviceModelSamples/");
// Create the ServiceHost and add an endpoint, then start
// the service.
ServiceHost myServiceHost =
new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
(contractType, myBinding, "secureCalculator");
myServiceHost.Open();
Dim security As SecurityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement()
' Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, False)
' Specify whether derived keys are needed.
security.SetKeyDerivation(True)
' Create the custom binding.
Dim myBinding As New CustomBinding(security, New HttpTransportBindingElement())
' Create the Type instances for later use and the Uri for
' the base address.
Dim contractType As Type = GetType(ICalculator)
Dim serviceType As Type = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8036/serviceModelSamples/")
' Create the ServiceHost and add an endpoint, then start
' the service.
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")
myServiceHost.Open()
Windows 認証をステートフルな SCT と組み合わせて使用すると、WCF では WindowsIdentity プロパティに実際の呼び出し元の ID が設定されず、代わりに "anonymous" が設定されます。 その場合、WCF のセキュリティは、受信 SCT からの要求ごとにサービスのセキュリティ コンテキストの内容を再作成する必要があるため、サーバーはメモリ内でセキュリティ セッションを追跡できません。 また、WindowsIdentity インスタンスは SCT にシリアル化できないため、WindowsIdentity プロパティは匿名 ID を返します。
次の構成は、この動作を示します。
<customBinding>
<binding name="Cancellation">
<textMessageEncoding />
<security
requireSecurityContextCancellation="false">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>