无效的模拟令牌 - 自 IIS 7 以来无法复制
本文关键字:复制 IIS 模拟 令牌 无效 | 更新日期: 2023-09-27 18:35:58
我有一个站点,我们使用Windows身份验证设置自动登录,如果失败,它会要求用户名/密码以作为表单登录。
完成它的方式,我们将授权设置为具有特定页面的表单(Winlogin.aspx)。Winlogin.aspx是使用授权Windows设置的。在Winlogin.aspx.cs的代码中,它得到了这个。Request.ServerVariables["LOGON_USER"],并使用request使用用户的令牌创建一个FormsAuthenticationTicket。GetUserToken(),使用加密版本设置cookie,并将浏览器发送到登录.aspx页面以进行表单授权。
登录.aspx获取cookie,对其进行解密,并假设在授权成功后.aspx使用从Winlog发送的用户创建的WindowsIdentity设置HttpContext.Current.User。
这已经在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);
我已经在上面呆了 2 天,试图弄清楚。
有人有想法吗?
要解决此问题,您必须使用未重复令牌中的WindowsIdentity
。因此,您必须传递HttpContext.User
传递的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...