设置HttpContext.Current.User

时间:2012-01-02 18:36:58

标签: ajax asp.net-mvc-3 authentication

我正在开发一个asp.net mvc 3.0应用程序,它具有简单的身份验证过程。用户填写一个表单,该表单通过ajax调用发送到服务器并获得响应,但问题是使用以下方法:

FormsAuthentication.SetAuthCookie(person.LoginName,false);

不足以填充'HttpContext.Current.User'并且需要运行以下方法:

FormsAuthentication.RedirectFromLoginPage("...");

问题在于,正如我所提到的,登录表单使用ajax表单,并使用json获取响应,因此无法重定向。

我怎么能填写'HttpContext.Current.User'?

感谢。

更新:

这是注册方法:

 [HttpPost]
        public ActionResult Register(Person person)
        {
            var q = da.Persons.Where(x => x.LoginName == person.LoginName.ToLower()).FirstOrDefault();

            if (q != null)
            {
                ModelState.AddModelError("", "Username is repettive, try other one");

                return Json(new object[] { false, this.RenderPartialViewToString("RegisterControl", person) });
            }
            else
            {
                if (person.LoginName.ToLower() == "admin")
                {
                    person.IsAdmin = true;
                    person.IsActive = true;
                }

                da.Persons.Add(person);

                da.SaveChanges();

                FormsAuthentication.SetAuthCookie(person.LoginName,false);
return Json(new object[] { true, "You have registered successfully!" });

}

}

3 个答案:

答案 0 :(得分:15)

FormsAuthentication不支持立即设置用户的身份,但您应该可以通过以下方式伪造它:

HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity(person.LoginName), new string[] { /* fill roles if any */ });

答案 1 :(得分:9)

这是我最终使用的版本,它基于@ AdamTuliper-MSFT的答案。它只能在登录后立即使用,但在重定向之前,允许其他代码访问HttpContext.User

  • 如果已经过身份验证,请不要执行任何操作
  • 不修改cookie,因为这只应该用于此请求的生命周期
  • 缩短一些内容,使用userdata更安全一些(绝不应为null,但是......)

调用SetAuthCookie()后调用此方法,如下所示:

// in login function
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
AuthenticateThisRequest();

private void AuthenticateThisRequest()
{
    //NOTE:  if the user is already logged in (e.g. under a different user account)
    //       then this will NOT reset the identity information.  Be aware of this if
    //       you allow already-logged in users to "re-login" as different accounts 
    //       without first logging out.
    if (HttpContext.User.Identity.IsAuthenticated) return;

    var name = FormsAuthentication.FormsCookieName;
    var cookie = Response.Cookies[name]; 
    if (cookie != null)
    {   
        var ticket = FormsAuthentication.Decrypt(cookie.Value);
        if (ticket != null && !ticket.Expired)
        {
            string[] roles = (ticket.UserData as string ?? "").Split(',');
            HttpContext.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
        }
    }
}

编辑:删除对Request.Cookies的调用,如@ AdamTuplier-MSFT所述。

答案 2 :(得分:6)

您需要手动设置它。不要重新发明轮子,请注意此处有关更新请求的当前主体的部分 - 这就是您的选择。

How to set Request.IsAuthenticated to true when not using FormsAuthentication.RedirectFromLoginPage?

public void RenewCurrentUser()
{
    System.Web.HttpCookie authCookie =
        System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = null;
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);

if (authTicket != null && !authTicket.Expired) { FormsAuthenticationTicket newAuthTicket = authTicket; if (FormsAuthentication.SlidingExpiration) { newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket); } string userData = newAuthTicket.UserData; string[] roles = userData.Split(','); System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles); } }

}