Windows中的WindowsIdentity.Impersonate随机出现“用于模仿的无效令牌 - 它无法复制”

时间:2021-07-21 08:09:59

I have an ASP.NET app that requires users to sign in with their domain accounts using Basic Authentication. The user can make a selection, then press a button.

我有一个ASP.NET应用程序,要求用户使用基本身份验证登录其域帐户。用户可以进行选择,然后按下按钮。

At some point after pressing the button is this code: WindowsIdentity.Impersonate(userIdentity.Token). userIdentity is of type WindowsIdentity, and it was previously set to (WindowsIdentity)User.Identity.

在按下按钮后的某个时刻是这段代码:WindowsIdentity.Impersonate(userIdentity.Token)。 userIdentity的类型为WindowsIdentity,之前设置为(WindowsIdentity)User.Identity。

userIdentity is stored as a session variable, and I think that's because, after the button is pressed, the page containing this code is called via AJAX.

userIdentity存储为会话变量,我认为这是因为按下按钮后,包含此代码的页面将通过AJAX调用。

When I hit this code, it works about 2/3 of the time, but 1/3 of the time, I get this exception: Invalid token for impersonation - it cannot be duplicated. I think the biggest head scratcher for me is why does it work sometimes but not other times? On some sessions, it works several times before failing. On others, it fails right away.

当我点击这段代码时,它大约有2/3的时间,但是1/3的时间,我得到了这个例外:用于模仿的无效令牌 - 它不能被复制。我觉得对我来说最大的问题是它为什么有时会起作用而不是其他时候?在某些会话中,它会在失败之前运行几次。在其他人,它立即失败。

Here's the stack trace:

这是堆栈跟踪:

at System.Security.Principal.WindowsIdentity.CreateFromToken(IntPtr userToken)

在System.Security.Principal.WindowsIdentity.CreateFromToken(IntPtr userToken)

at System.Security.Principal.WindowsIdentity..ctor(IntPtr userToken, String authType, Int32 isAuthenticated)

在System.Security.Principal.WindowsIdentity..ctor(IntPtr userToken,String authType,Int32 isAuthenticated)

at System.Security.Principal.WindowsIdentity.Impersonate(IntPtr userToken)

在System.Security.Principal.WindowsIdentity.Impersonate(IntPtr userToken)

at Resource_Booker.BLL.ReservationAgent.SubmitReservationRequest(Reservation reservation, Patron patron) in C:\dev\RoomRes\Resource Booker\BLL\ReservationAgent.cs:line 101

at Resource_Booker.BLL.ReservationAgent.SubmitReservationRequest(预订,Patron赞助人)在C:\ dev \ RoomRes \ Resource Booker \ BLL \ ReservationAgent.cs:第101行

at Resource_Booker.Reserve.reserve_Click(Object sender, EventArgs e) in C:\dev\RoomRes\Resource Booker\Reserve.aspx.cs:line 474

在C:\ dev \ RoomRes \ Resource Booker \ Reserve.aspx.cs中的Resource_Booker.Reserve.reserve_Click(Object sender,EventArgs e):第474行

at System.EventHandler.Invoke(Object sender, EventArgs e)

在System.EventHandler.Invoke(Object sender,EventArgs e)

at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)

在System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

在System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)

Here's a confounding factor: I cannot reproduce this problem on my local Windows 7 x64 workstation--albeit my authentication is passed implicitly here since I am using localhost--or on a Windows 2003 32-bit IIS 6.0 environment. It only happens on a pretty vanilla Windows 2008 R2 environment. All these environments are domain members.

这是一个令人困惑的因素:我无法在我的本地Windows 7 x64工作站上重现此问题 - 虽然我的身份验证是在此处隐式传递的,因为我使用的是localhost - 或者在Windows 2003 32位IIS 6.0环境中。它只发生在一个漂亮的Windows 2008 R2环境中。所有这些环境都是域成员。

1 个解决方案

#1


9  

Basically what you are seeing is not a security problem as the logon session is cached by IIS for the lifetime of the TCP connection, but HTTP will occasionally cut the TCP connection requiring re-authentication. This will happen seamlessly and invisibly (handled by the browser) but it will invalidate the token, as the logon session will be destroyed when the TCP connection ends.

基本上你所看到的并不是安全问题,因为在TCP连接的生命周期中,IIS会缓存登录会话,但HTTP偶尔会切断需要重新身份验证的TCP连接。这将无缝地和不可见地发生(由浏览器处理)但它将使令牌无效,因为当TCP连接结束时将破坏登录会话。

I.e. for the benefit of @usr, it only works sometimes because the logon session is the same so the token is the same, so the token stored in the session works because it happens to be the same actual token as User.Identity. It's not a way of avoiding the security check it is an implementation detail of the security check.

即为了@usr的利益,它只能工作,因为登录会话是相同的,因此令牌是相同的,因此存储在会话中的令牌可以工作,因为它恰好是与User.Identity相同的实际令牌。这不是避免安全检查的一种方式,它是安全检查的实现细节。

You shouldn't be storing the identity in the session - it is unnecessary since it is an authenticated connection.

您不应该在会话中存储身份 - 这是不必要的,因为它是经过身份验证的连接。

Just use (WindowsIdentity)User.Identity every single time and your problem should go away.

只需每次使用(WindowsIdentity)User.Identity,您的问题就会消失。

#1


9  

Basically what you are seeing is not a security problem as the logon session is cached by IIS for the lifetime of the TCP connection, but HTTP will occasionally cut the TCP connection requiring re-authentication. This will happen seamlessly and invisibly (handled by the browser) but it will invalidate the token, as the logon session will be destroyed when the TCP connection ends.

基本上你所看到的并不是安全问题,因为在TCP连接的生命周期中,IIS会缓存登录会话,但HTTP偶尔会切断需要重新身份验证的TCP连接。这将无缝地和不可见地发生(由浏览器处理)但它将使令牌无效,因为当TCP连接结束时将破坏登录会话。

I.e. for the benefit of @usr, it only works sometimes because the logon session is the same so the token is the same, so the token stored in the session works because it happens to be the same actual token as User.Identity. It's not a way of avoiding the security check it is an implementation detail of the security check.

即为了@usr的利益,它只能工作,因为登录会话是相同的,因此令牌是相同的,因此存储在会话中的令牌可以工作,因为它恰好是与User.Identity相同的实际令牌。这不是避免安全检查的一种方式,它是安全检查的实现细节。

You shouldn't be storing the identity in the session - it is unnecessary since it is an authenticated connection.

您不应该在会话中存储身份 - 这是不必要的,因为它是经过身份验证的连接。

Just use (WindowsIdentity)User.Identity every single time and your problem should go away.

只需每次使用(WindowsIdentity)User.Identity,您的问题就会消失。