2011-09-12 4 views
3

キャッシュのSystem.Web.Caching.Cache実装を使用してデータを格納するイントラネットを開発しています。私は周りを取得するように見えることはできません 「安全ハンドルが閉じられました」エラーが、それは以下のスタックトレースで生成されますASP.NET MVC 3のユーザーごとのキャッシュで「安全なハンドルが閉じられました」

エラーは次の行で生成される
[ObjectDisposedException: Safe handle has been closed] 
System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) +0 
Microsoft.Win32.Win32Native.GetTokenInformation(SafeTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength) +0 
System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeTokenHandle tokenHandle, TokenInformationClass tokenInformationClass) +203 
System.Security.Principal.WindowsIdentity.get_User() +94 
System.Security.Principal.WindowsIdentity.GetName() +127 
System.Security.Principal.WindowsIdentity.get_Name() +42 

@if(intranet.Models.NyhederModels.isAdministrator(CachedVariables.getWP(User))) 

次のようにgetWPである場合:

public static WindowsPrincipalEx getWP(System.Security.Principal.IPrincipal User) 
{ 
    Cache context = HttpRuntime.Cache; 
    WindowsPrincipalEx wp = context["windowsPrincipal_" + User.Identity.Name] as WindowsPrincipalEx; 
    if (wp == null) 
    { 
     wp = new intranet.Models.WindowsPrincipalEx(User.Identity); 
     context.Insert("windowsPrincipal_" + User.Identity.Name, wp, null, DateTime.Now.AddSeconds(15.0), Cache.NoSlidingExpiration); 
    } 
    return wp; 
} 

をあなたが見ることができるように、キャッシュへの鍵は、キャッシュされたデータは、ユーザー単位であることを確認するために、のUserPrincipalをとります。キャッシュが部分的に動作するHttpContext.Currentを使用してみましたが、これはリクエストごとに発生するため、データは各ページごとに一度取得されます。

上記のコードは、ローカルホスト上で問題なく動作しますが、実稼働環境で実行すると「安全なハンドルが閉じられました」と表示されます。

キャッシュされるデータは、Windows Active Directoryへのクエリの結果です。違いがあれば、UserはSystem.Security.Principal.IPrincipalのインスタンスです。

キャッシングを導入した後でのみ表示されるこのエラーに関する考えはありますか?

これは、古い質問の少しですが、私はGoogleで「安全なハンドルは原則キャッシングを閉じている」の検索今日、この全体に走っ事前

答えて

1

でいただきありがとうございます。

WindowsPrincipalオブジェクトをHttpContext.Cacheに追加したときに同じエラーが表示されるため、偽装用に再利用できるようになりました。私はこのエラーが発生し始めた。このエラーは、WindowsPrincipalオブジェクトを格納するのではなく、WindowsIdentity.Tokenだけを格納する代わりに、新しいWindowsPrincipalを作成して、キャッシュされたWindowsIdentity.Tokenを渡しているということです。

+0

オプションであろうと、私の状況にかかわらず、 DBの相互作用はPrincipalオブジェクトの作成時に行われるため、トークンをキャッシュしても、それぞれの新しい要求では発生しない操作は保存されません。 – dougajmcdonald

1

上記の回答は私には役に立たなかった。実際には、最初は機能しましたが、サイトがページを起動するときにサイトはユーザーIDを何度もリセットする必要があります。 3回目にトークンで原則を作成するコードが呼び出されたとき、このエラーが「偽装のトークンが無効です - 複製できません」と表示されます。全く分からない。

HttpContext.Current.User = (new WindowsPrincipal(new WindowsIdentity((IntPtr)Session["IdentityToken"]))); 

は、私はようやく私の問題を解決するために、いくつかのブルートフォースを使用していた [2012年11月21日編集します]。セッションにユーザーID(文字列)のみを保存し、毎回ID /プリンシパルを再作成します。私は突然の問題を引き起こしたかもしれない自動MS Windowsのアップデート(10/18)に疑念がありますが、現時点では確信はありません。

WindowsIdentity identity = new WindowsIdentity(HttpContext.Current.Session["UserID"].ToString()); 
HttpContext.Current.User = new WindowsPrincipal(identity); 
0

@Prethenの答え(これは私を助けた!)は、ここに私のために例外「安全なハンドルがを閉じている」引き起こしたコードです:

return RequestContext.Principal.Identity.Name; 

は、ここでそれを修正するものです。

WindowsIdentity identity = WindowsIdentity.GetCurrent(); 
HttpContext.Current.User = new WindowsPrincipal(identity); 
return RequestContext.Principal.Identity.Name; 
関連する問題