我有一个网站,我们使用Windows身份验证设置自动登录,如果失败,则要求输入用户名/密码作为表单。
完成它的方式后,我们将授权设置为具有特定页面的表单(Winlogin.aspx)。 Winlogin.aspx是使用授权Windows设置的。在Winlogin.aspx.cs的代码中,它获取this.Request.ServerVariables [“LOGON_USER”]并使用request.GetUserToken()创建带有用户令牌的FormsAuthenticationTicket,设置带有加密版本的cookie并将浏览器发送到表单授权的login.aspx页面。
Login.aspx获取cookie,对其进行解密,并假设使用从授权成功后从Winlog.aspx发送的用户创建的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天了。
有人有想法吗?
答案 0 :(得分:0)
要解决此问题,您必须使用未重复的令牌中的WindowsIdentity
。因此,您必须传递HttpContext.User
传递WindowsPrinciple
的{{1}},该WindowsIdentity
由原始令牌(不重复)生成。我一直试图想办法绕过这个,但看起来唯一的方法是每次需要LogonUser
时存储凭据而不是身份和登录(请参阅WindowsIdentity
)
您无法重复使用原始令牌,因为HttpContext.User
会在每次请求后处理(出于安全原因)。
答案 1 :(得分:0)
我认为问题是,您不能在另一个请求中重用WindowsPrincipal的同一实例,因为可能包含分配给WindowsPrincipal的某些引用的SafeHandle实例已与先前的请求一起使用,并且您不能复制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...