C# 用于模拟的令牌无效-由于IIS 7,因此无法复制该令牌

C# 用于模拟的令牌无效-由于IIS 7,因此无法复制该令牌,c#,asp.net,iis,C#,Asp.net,Iis,我有一个网站,在那里我们用windows身份验证设置自动登录,如果失败,它会要求用户名/密码作为表单登录 按照这种方式,我们将授权设置为带有特定页面(Winlogin.aspx)的表单。 Winlogin.aspx是使用授权窗口设置的。在Winlogin.aspx.cs的代码中,它获取this.Request.ServerVariables[“LOGON\u USER”]并使用Request.GetUserToken()使用用户的令牌创建FormsAuthenticationTicket,设置具

我有一个网站,在那里我们用windows身份验证设置自动登录,如果失败,它会要求用户名/密码作为表单登录

按照这种方式,我们将授权设置为带有特定页面(Winlogin.aspx)的表单。 Winlogin.aspx是使用授权窗口设置的。在Winlogin.aspx.cs的代码中,它获取this.Request.ServerVariables[“LOGON\u USER”]并使用Request.GetUserToken()使用用户的令牌创建FormsAuthenticationTicket,设置具有加密版本的cookie,并将浏览器发送到login.aspx页面以获得表单授权

Login.aspx获取cookie,对其进行解密,并假设将HttpContext.Current.User设置为WindowsIdentity,该WindowsIdentity是在授权成功后从Winlog.aspx发送的用户创建的

这已经在IIS6上完美地工作了一年多了 但是 我们正在更新服务器并移动到IIS 7,但现在我得到了一个用于模拟的无效令牌-它无法复制

这是使用的代码

// Extract the roles from the cookie, and assign to our current principal, which is attached to the HttpContext.
FormsAuthenticationTicket winAuthTicket = FormsAuthentication.Decrypt(authCookie.Value);
String token = winAuthTicket.UserData;
IntPtr userToken = new IntPtr(int.Parse(token);

-----> Line that gives error now. <-----
WindowsIdentity identity = new WindowsIdentity(userToken, "NTLM", WindowsAccountType.Normal, true); 

HttpContext.Current.User = new WindowsPrincipal(identity);
//从cookie中提取角色,并分配给当前主体,该主体附加到HttpContext。
FormsAuthenticationTicket winAuthTicket=FormsAuthentication.Decrypt(authCookie.Value);
字符串标记=winAuthTicket.UserData;
IntPtr userToken=新的IntPtr(int.Parse(token));

----->现在出现错误的行。要解决此问题,您必须使用未复制的令牌中的
WindowsIdentity
。因此,您必须传递
HttpContext.User
a
WindowsPrinciple
,该令牌是由原始令牌(未复制)生成的
WindowsIdentity
。我一直在试图找到一种绕过此问题的方法,但似乎唯一的方法是在每次需要
WindowsIdentity
时存储凭据,而不是身份和登录(请参见
LogonUser


您无法重新使用原始令牌,因为
HttpContext.User
在每次请求后都会被释放(出于安全原因).

我认为问题在于,您不能在另一个请求中重用相同的WindowsPrincipal实例,因为SafeHandle实例(可能包含一些分配给WindowsPrincipal的引用)已与上一个请求一起处理,并且您不能复制WindowsIdentity.Token-必须重新生成它。您已经克隆WindowsIdentity-这将消除引用依赖项。然后,您可以通过WindowsIdentity.token或其他方式重新生成网站身份验证令牌

我也遇到过同样的问题,我就是这样解决的

var user = new WindowsPrincipal(((WindowsIdentity)HttpContext.Current.User.Identity).Clone());
//now assign the user again to the current context's user or do some other stuff like storing the clone to session for future requests...

可能的副本您是否为此找到解决方案?