ジュネーブ関連の質問はまだあまり見たことがありません。ジュネーブ フォーラムにもこの質問を投稿しました...
私は、幅広いインストールベースを持つ win フォーム アプリがあるシナリオに取り組んでいます。このアプリは、その運用全体を通じて、私たちがホストするさまざまなサービスに頻繁に呼び出しを発行します。
サービスはすべてジュネーブ フレームワークを使用しており、すべてのクライアントは、サービスへのアクセスを許可するトークンを発行するために、まず STS に電話する必要があります。
ws2007FederationHttpBinding を使用してすぐに使用できるように、各サービス呼び出しの前に STS からトークンを取得するようにアプリを構成できますが、サービスを呼び出す作業がほとんど重複しているため、明らかにこれは最も効率的な方法ではありません。
または、アプリから「手動で」トークンを取得するために必要なコードを実装し、サービスで操作を呼び出すときに、事前に取得した同じトークンを渡します (WSTrustClient サンプルとフォーラムのヘルプに基づく)。それはうまく機能するので、解決策はありますが、コードで WCF チャネルを構築する必要があり、素晴らしい WCF 構成から離れているため、あまり洗練されていないと思います。
私は ws2007FederationHttpBinding アプローチを好みます。クライアントは、Geneva について何も知らずに、他の WCF サービスと同じようにサービスを呼び出すだけで、バインディングがトークン交換を処理します。
その後、誰か (Jon Simpson) が [私が思うに] 素晴らしいアイデアをくれました - アプリ自体でホストされ、ローカルで取得したトークンをキャッシュするサービスを追加します。ローカル キャッシュ サービスは、STS と同じコントラクトを実装します。リクエストを受信すると、キャッシュされたトークンが存在するかどうかを確認し、存在する場合はそれを返し、存在しない場合は「実際の」STS を呼び出し、新しいトークンを取得し、キャッシュして返します。クライアント アプリは引き続き ws2007FederationHttpBinding を使用できますが、発行者として STS を使用する代わりに、ローカル キャッシュを使用します。
このようにして、サービス固有のカスタム コードを使用せずにトークンをキャッシュするという、両方の長所を実現できると思います。キャッシュはすべての RP のトークンを処理できる必要があります。
私はそれが機能するかどうかを確認するために非常に単純なプロトタイプを作成しました.
私のローカル サービス (現在はコンソール アプリ) が要求を取得し、最初に STS を呼び出してトークンを取得し、それをキャッシュして、正常にクライアントに返します。その後、クライアントはそれを使用して RP を呼び出します。すべてうまくいきます。
ただし、2 回目は、ローカルのキャッシュ サービスが同じトークンを再度使用しようとしますが、クライアント側は MessageSecurityException で失敗します -
「セキュリティ プロセッサは、メッセージ内のセキュリティ ヘッダーを見つけることができませんでした。これは、メッセージがセキュリティで保護されていない障害であるか、通信する当事者間にバインディングの不一致があるためである可能性があります。これは、サービスがセキュリティ用に構成されていて、クライアントがセキュリティを使用していません。」
同じトークンが複数回使用されるのを妨げているものはありますか? WSTrustClient サンプルに従ってトークンを再利用したとき、うまく機能したので、私はそれを疑っています。私は何が欠けていますか?私の考えは可能ですか?いいもの?
これは、ローカルキャッシュの(この段階では非常に基本的な)メインコードビットです-
static LocalTokenCache.STS.Trust13IssueResponse cachedResponse = null;
public LocalTokenCache.STS.Trust13IssueResponse Trust13Issue(LocalTokenCache.STS.Trust13IssueRequest request)
{
if (TokenCache.cachedResponse == null)
{
Console.WriteLine("cached token not found, calling STS");
//create proxy for real STS
STS.WSTrust13SyncClient sts = new LocalTokenCache.STS.WSTrust13SyncClient();
//set credentials for sts
sts.ClientCredentials.UserName.UserName = "Yossi";
sts.ClientCredentials.UserName.Password = "p@ssw0rd";
//call issue on real sts
STS.RequestSecurityTokenResponseCollectionType stsResponse = sts.Trust13Issue(request.RequestSecurityToken);
//create result object - this is a container type for the response returned and is what we need to return;
TokenCache.cachedResponse = new LocalTokenCache.STS.Trust13IssueResponse();
//assign sts response to return value...
TokenCache.cachedResponse.RequestSecurityTokenResponseCollection = stsResponse;
}
else
{
}
//...and reutn
return TokenCache.cachedResponse;