2011-10-26 13 views
0

IISでwsHttpBindingを使用して一連のWCFサービスをセットアップし、リクエストを行っているユーザーを特定するカスタムセキュリティ(メッセージヘッダーを使用)を実装しました。 WCFエンドポイントが受け取ったすべての要求が新しいスレッドで終了するということは、数年間のnetTcpBindingエクスペリエンス(IISではなく、Windowsサービスを使用して)をベースにしています。この仮定を使用して、(IDispatchMessageInspectorを実装して)私のカスタムセキュリティクラスがそうのようなメッセージヘッダに「トークン」(GUID)を見つけることに基づいて、スレッドIDを設定します。WCF wsHttpBinding with IIS

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext) 
{ 
    string token = string.Empty; 
    if (request.Headers.FindHeader("SecurityToken", Primitives.SerializationNamespace) > -1) 
     token = request.Headers.GetHeader<string>("SecurityToken", Primitives.SerializationNamespace); 

    if (!string.IsNullOrEmpty(token)) 
     Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(token, "AppName"), new string[] { "testrole" }); 
    else 
     Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("guest", "AppName"), new string[] { }); 
    } 

    return null; 
} 

このかかわらず、テストでは、と私にもかかわらず、 ThreadStaticとマークされた内部変数(ユーザーオブジェクトを含む)は、新しい要求が前の呼び出し元のIDを保持しているようです。

ここでは例です:

[ThreadStatic] 
private static User _CurrentUser = null; 

internal static User CurrentUser 
    { 
     get 
     { 
      //this holds the value of the previous caller's identity still, even though the 
      //thread's Identity.Name is now equal to the new caller's Guid 
      if (_CurrentUser == null) 
        _CurrentUser = UserData.GetByToken(Thread.CurrentPrincipal.Identity.Name); 


      return _CurrentUser; 
     } 
    } 

私も次の属性と私のサービス実装の(直接.SVCファイルの背後にある)のすべてをマーキングしようとしたが、それは何も変更しませんでした:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 

すべてのリクエストをどのように保証できるかについてのアイデアは、新しいスレッドにありますか?または、要求を作成しているユーザーが重複していない場合、誰が格納するかを決定する良い方法がありますか?

+0

なぜあなたは 'ThreadStatic'で遊んでいますか?あなたは何を達成しようとしていますか? –

答えて

2

あなたのコントロールの下でスレッディングがない環境で変数ThreadStaticを使用すると、災害につながります。 WCF(IISとself-hosted)とASP.NETはどちらも内部的にスレッドプールを使用します=各要求は別々のスレッドによって処理されますが、これらのスレッドは後続の要求に再利用され、回避する方法はありません。

OperationContextextensionを使用して、ThreadStatic変数の代わりにユーザーを保存します。

+0

私はそれが私が必要としていたものだと思います。もう少しテストしますが、完璧に動作するように見えます。ありがとう! – RubyHaus

関連する問題