在ASP中,每个用户缓存的“安全句柄已经关闭”。净MVC 3

时间:2022-10-26 23:57:19

I'm developing an intranet where I store data using the System.Web.Caching.Cache implementation of caching. I can't seem to get around the "Safe handle has been closed" error, that is produced with the following stacktrace:

我正在开发一个内部网,在这里我使用system . web . cache存储数据。缓存的缓存实现。我似乎无法回避“安全句柄已关闭”的错误,这是由以下stacktrace生成的:

[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

The error is generated at the following line:

错误产生于以下行:

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

Where getWP is as follows:

其中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;
}

As you can see, the key into the cache takes the UserPrincipal, to make sure the cached data is on a per-user basis. I tried using HttpContext.Current, where the caching partially works, but since this happens on a per-request basis, the data is still retrieved once for every page.

如您所见,缓存中的键接受UserPrincipal,以确保缓存的数据是基于每个用户的。我试着使用HttpContext。当前,缓存部分工作,但是由于这是在每个请求的基础上发生的,所以仍然为每个页面检索一次数据。

The above code works flawlessly on the localhost but shows the "Safe handle has been closed" when run in production environment.

上述代码在本地主机上运行良好,但在生产环境中运行时显示“安全句柄已关闭”。

The data being cached is the result of a query into Windows Active Directory, if that makes any difference and User is an instance of System.Security.Principal.IPrincipal.

缓存的数据是查询到Windows Active目录的结果,如果这有什么不同的话,并且用户是System.Security.Principal.IPrincipal的实例。

Any thoughts on this error, which only appeared after introducing the caching?

对于这个错误(只有在引入缓存之后才出现)有什么想法吗?

Thank you in advance

提前谢谢你

3 个解决方案

#1


1  

This is a little of an old question, but I ran across this today searching for "Safe handle has been closed principle caching" on google.

这是一个老问题,但是我今天在谷歌上搜索“安全句柄已关闭原则缓存”时遇到了这个问题。

I am getting the same error when I added my WindowsPrincipal object to HttpContext.Cache so that I could reuse it for impersonation. I started getting this error. What I did to stop this error from happening is that instead of storing a WindowsPrincipal object I store just the WindowsIdentity.Token, and I create a new WindowsPrincipal with a new WindowsIdentiy, passing in the Cached WindowsIdentity.Token.

当我将WindowsPrincipal对象添加到HttpContext时,我也会得到相同的错误。缓存,以便我可以重用它来模拟。我开始得到这个错误。为了阻止这个错误的发生,我没有存储WindowsPrincipal对象,而是只存储WindowsIdentity。令牌,我用一个新的WindowsIdentiy创建一个新的WindowsPrincipal,并传入缓存的WindowsIdentity.Token。

#2


1  

The above answer didn't work for me. Actually, it worked initially, but the site needs to reset the user ID multiple times behind the scenes as the site launches a page. On the 3rd time the code is called to create a Principle with the Token, I get this error "Invalid token for impersonation - it cannot be duplicated." No clue.

上面的答案对我不起作用。实际上,它最初是工作的,但是站点需要在站点启动页面时将用户ID多次重置。在第3次调用代码创建一个使用该标记的原则时,我得到这个错误“无效的模拟标记—它不能被复制”。没有线索。

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

[edited 11/21/2012] I finally had to use some brute force to solve my problem. I simply save only the User ID (a string) in session and recreate the Identity/Principal each time. I'm suspicious of an automatic MS Windows update (on 10/18) that might have caused the issue all of a sudden, but not sure at this time.

[编辑11/21/2012]我最终不得不使用蛮力来解决我的问题。我只在会话中只保存用户ID(一个字符串),每次都重新创建身份/主体。我怀疑自动的MS Windows更新(10/18)可能会突然引起问题,但目前还不确定。

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

#3


0  

Following on from @Prethen's answer (which helped me out!), here's the code that was causing the “Safe handle has been closed” exception for me:

下面是@Prethen的回答(帮助了我!),下面是导致“安全句柄已关闭”异常的代码:

return RequestContext.Principal.Identity.Name;

Here's what fixed it:

这是固定的:

WindowsIdentity identity = WindowsIdentity.GetCurrent();
HttpContext.Current.User = new WindowsPrincipal(identity);
return RequestContext.Principal.Identity.Name;

#1


1  

This is a little of an old question, but I ran across this today searching for "Safe handle has been closed principle caching" on google.

这是一个老问题,但是我今天在谷歌上搜索“安全句柄已关闭原则缓存”时遇到了这个问题。

I am getting the same error when I added my WindowsPrincipal object to HttpContext.Cache so that I could reuse it for impersonation. I started getting this error. What I did to stop this error from happening is that instead of storing a WindowsPrincipal object I store just the WindowsIdentity.Token, and I create a new WindowsPrincipal with a new WindowsIdentiy, passing in the Cached WindowsIdentity.Token.

当我将WindowsPrincipal对象添加到HttpContext时,我也会得到相同的错误。缓存,以便我可以重用它来模拟。我开始得到这个错误。为了阻止这个错误的发生,我没有存储WindowsPrincipal对象,而是只存储WindowsIdentity。令牌,我用一个新的WindowsIdentiy创建一个新的WindowsPrincipal,并传入缓存的WindowsIdentity.Token。

#2


1  

The above answer didn't work for me. Actually, it worked initially, but the site needs to reset the user ID multiple times behind the scenes as the site launches a page. On the 3rd time the code is called to create a Principle with the Token, I get this error "Invalid token for impersonation - it cannot be duplicated." No clue.

上面的答案对我不起作用。实际上,它最初是工作的,但是站点需要在站点启动页面时将用户ID多次重置。在第3次调用代码创建一个使用该标记的原则时,我得到这个错误“无效的模拟标记—它不能被复制”。没有线索。

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

[edited 11/21/2012] I finally had to use some brute force to solve my problem. I simply save only the User ID (a string) in session and recreate the Identity/Principal each time. I'm suspicious of an automatic MS Windows update (on 10/18) that might have caused the issue all of a sudden, but not sure at this time.

[编辑11/21/2012]我最终不得不使用蛮力来解决我的问题。我只在会话中只保存用户ID(一个字符串),每次都重新创建身份/主体。我怀疑自动的MS Windows更新(10/18)可能会突然引起问题,但目前还不确定。

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

#3


0  

Following on from @Prethen's answer (which helped me out!), here's the code that was causing the “Safe handle has been closed” exception for me:

下面是@Prethen的回答(帮助了我!),下面是导致“安全句柄已关闭”异常的代码:

return RequestContext.Principal.Identity.Name;

Here's what fixed it:

这是固定的:

WindowsIdentity identity = WindowsIdentity.GetCurrent();
HttpContext.Current.User = new WindowsPrincipal(identity);
return RequestContext.Principal.Identity.Name;