コンテキスト交換プロトコル
このセクションでは、Windows Communication Foundation (WCF) .NET Framework Version 3.5 リリースで導入されたコンテキスト交換プロトコルについて説明します。このプロトコルを使用すると、クライアント チャネルはサービスから送られたコンテキストを受け入れ、以降はそのコンテキストを、同じクライアント チャネル インスタンス経由でそのサービスに送信されるすべての要求に適用できます。コンテキスト交換プロトコルを実装されると、2 つの機構 (HTTP Cookie または SOAP ヘッダー) のいずれか 1 つを使用し、サーバーとクライアント間でコンテキストを伝達できます。
コンテキスト交換プロトコルは、カスタム チャネル層に実装されます。チャネルでは ContextMessageProperty プロパティを使用して、アプリケーション層とコンテキストを送受信します。エンドポイント間の転送については、コンテキストの値は、チャネル層で SOAP ヘッダーとしてシリアル化されるか、HTTP 要求および応答を表すメッセージ プロパティとの間で双方向に変換されます。後者の場合、下位のチャネル層のいずれか 1 つで、HTTP 要求および応答のメッセージ プロパティをそれぞれ HTTP Cookie との間で双方向に変換する必要があります。コンテキスト交換に使用する機構の選択は、ContextBindingElement の ContextExchangeMechanism プロパティを使用します。有効な値は、HttpCookie または SoapHeader です。
クライアントでは、チャネルのインスタンスは Enabled チャネル プロパティの設定値に基づいて 2 つのモードで動作します。
モード 1: チャネル コンテキスト管理
これは、Enabled を true に設定した場合の既定のモードです。このモードでは、コンテキスト チャネルはコンテキストを管理し、その有効期間中、コンテキストをキャッシュします。コンテキストは、GetContext メソッドを呼び出して、IContextManager チャネル プロパティ経由でチャネルから取得できます。チャネルを開く前に、チャネル プロパティで SetContext メソッドを呼び出して、事前に特定のコンテキストで初期化できます。チャネルは一度コンテキストで初期化すると、リセットできません。
このモードのインバリアントの一覧を次に示します。
チャネルを開いた後に SetContext を使用してコンテキストをリセットしようとすると、InvalidOperationException がスローされます。
送信メッセージで ContextMessageProperty を使用してコンテキストを送信しようとすると、InvalidOperationException がスローされます。
特定のコンテキストを持つサーバーからメッセージを受信する場合に、チャネルが既に特定のコンテキストで初期化されていると、ProtocolException が発生します。
メモ : 明示的にコンテキストが設定されていないチャネルを開いている場合に限り、サーバーから初期コンテキストを受信するのが適切です。 受信メッセージの ContextMessageProperty は常に null です。
モード 2: アプリケーション コンテキスト管理
これは、Enabled を false に設定した場合のモードです。このモードでは、コンテキスト チャネルでコンテキストを管理しません。コンテキストの取得、管理、および適用は、ContextMessageProperty を使用してアプリケーションで行う必要があります。GetContext または SetContext を呼び出そうとすると、InvalidOperationException が発生します。
どちらのモードを選択しても、クライアント チャネル ファクトリは、IRequestChannel、IRequestSessionChannel、および IDuplexSessionChannel の各メッセージ交換パターンをサポートします。
サービスでは、チャネルのインスタンスが、受信メッセージでクライアントから送られたコンテキストを ContextMessageProperty に変換します。これで、アプリケーション層、または呼び出しスタックの上位に位置する他のチャネルから、メッセージ プロパティにアクセスできるようになります。サービス チャネルを使用し、応答メッセージに ContextMessageProperty をアタッチすることによって、クライアントに返される新しいコンテキスト値をアプリケーション層で指定することもできます。このプロパティは、コンテキストを含む SOAP ヘッダーまたは HTTP Cookie に変換されます。どちらに変換されるかは、バイディングの構成によって決まります。サービス チャネル リスナは、IReplyChannel、IReplySessionChannel、および IReplySessionChannel の各メッセージ交換パターンをサポートします。
コンテキスト交換プロトコルは、コンテキストの伝達に HTTP Cookie を使用しない場合にコンテキスト情報を表す新しい wsc:Context SOAP ヘッダーを使用します。コンテキスト ヘッダー スキーマでは、文字列キーと文字列コンテンツを持つ任意の数の子要素を使用できます。コンテキスト ヘッダーの例を次に示します。
<Context xmlns="https://schemas.microsoft.com/ws/2006/05/context">
<property name="myContext">context-2</property>
</Context>
HttpCookie モードの場合、SetCookie ヘッダーを使用して Cookie が設定されます。Cookie の名前は WscContext です。Cookie の値は、wsc:Context ヘッダーの Base64 エンコーディングです。この値は引用符で囲まれます。
WS-Addressing ヘッダーを保護するのと同じ理由により、コンテキスト値は、転送中に変更されないように保護する必要があります。WS-Addressing ヘッダーは、サービスで要求のディスパッチ先を確認するのに使用されます。したがって、バインディングにメッセージ保護機能がある場合、SOAP レベルかトランスポート レベルのいずれかで wsc:Context ヘッダーにデジタル署名するか、署名と暗号化を行う必要があります。HTTP Cookie を使用してコンテキストを伝達する場合は、トランスポート セキュリティを使用して保護する必要があります。
サービス エンドポイントでコンテキスト交換プロトコルのサポートを必要とする場合は、公開するポリシーにそのことを明示できます。新たに 2 つのポリシー アサーションが導入され、SOAP レベルでコンテキスト交換プロトコルをサポートしたり、HTTP Cookie のサポートを有効化したりするクライアント要件を示すことができます。このアサーションはサービスのポリシー内に生成されます。生成は次のように、ContextExchangeMechanism プロパティの値によって制御します。
ContextSoapHeader の場合は、次のアサーションが生成されます。
<IncludeContext xmlns=”https://schemas.microsoft.com/ws/2006/05/context” protectionLevel=”Sign” />
HttpCookie の場合は、次のアサーションが生成されます。
<HttpUseCookie xmlns=”https://schemas.xmlsoap.org/soap/http”/>