FormsAuthentication cookie不是持久的

时间:2012-06-29 17:26:49

标签: asp.net-mvc-3 cookies formsauthenticationticket

我正在尝试使用以下代码(在AccountController.cs中)将FormsAuthenticationTicket保存到cookie:

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket
          (1, user.UserEmail, DateTime.Now, 
           DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), 
           false, null);

string encTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName,
ticket.ToString());
HttpContext.Response.Cookies.Add(faCookie);

if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
           && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
           {
             return Redirect(returnUrl);
           }
           else
          {
             return RedirectToAction("Index", "Home");
          }

当我单步执行调试器时,一切似乎都很好。在我到达Application_AuthenticateRequest之前,我尝试检索cookie:

HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
         //do stuff here
        }

当我查看Cookies系列时,那里什么都没有。我可以在AccountController代码中添加另一个普通的cookie,它显示得很好。无论我是否包含UserData,问题仍然存在,因此我不认为这是一个大小问题。

感谢您提供的任何见解。

5 个答案:

答案 0 :(得分:2)

cookie的最大大小为4096字节。如果超过此值,则不会保存cookie。

使用以下方法检查Cookie大小:

int cookieSize = System.Text.UTF8Encoding.UTF8.GetByteCount(faCookie.Values.ToString());

答案 1 :(得分:1)

您正在将Cookie添加到响应中。完成后,请确保立即重定向。只有在随后的请求中,您才可以希望从Request.Cookies集合中读取它。

答案 2 :(得分:1)

虽然您的身份验证票证设置为持久性且具有过期日期,但实际的cookie不会。

创建Cookie时添加以下内容:

var faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
                   {
                       Expires = ticket.Expiration
                   };

答案 3 :(得分:1)

在编写cookie的代码中,不能使用加密cookie将null传递给userData参数。 IsPersistent为false是好的。

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket
          (1, user.UserEmail, DateTime.Now, 
           DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), 
           false, null);

执行以下操作: 在我的示例中,您可以用空字符串替换userData.ToString()。只是不要传递null!这应该可以解决你的问题。

 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
            1,                             // version
            userId.UserEmail,                      // a unique value that identifies the user
            DateTime.Now,                  // created
            DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),  // expires
            false,                    // persistent?
            userData.ToString(),   // user specific data (optional) //NOTE:  DO NOT pass NULL as encrypted string value will become NULL (argh)
            FormsAuthentication.FormsCookiePath  // the path for the cookie
            );

然后在你的global.asax.cs中 您将在FormsAuthentication_OnAuthenticate事件中检查该cookie 您的代码会有所不同,因为我已经编写了自定义表单身份验证,并且使用的是userId,而不是您的情况下的电子邮件。

如果在编写auth cookie时为UserData参数传递null,请注意以下逻辑失败。

    if (authCookie == null || authCookie.Value == "")
    {
        return;
    }

以下是globalasax.cs文件中的完整事件:

protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
{
    //STEP #1 of Authentication/Authorization flow
    //Reference:  http://msdn.microsoft.com/en-us/library/ff649337.aspx
    //==================================================================
    if (FormsAuthentication.CookiesSupported == true)
    {

        //Look for an existing authorization cookie when challenged via [Authorize]
        HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie == null || authCookie.Value == "")
        {
            return;
        }
        FormsAuthenticationTicket authTicket = null;
        try
        {
            //Reading from the ticket
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            //Check the Cookiename (which in this case is UserId).  If it is null, then we have an issue
            if (authTicket.Name == null)
            {
                FormsAuthentication.SignOut();
                authCookie.Value = null;
            }

        }
        catch (Exception ex)
        {
            //Unable to decrypt the auth ticket
            return;
        }

        //get userId from ticket
        string userId = authTicket.Name;


        Context.User = new GenericPrincipal(
                  new System.Security.Principal.GenericIdentity(userId, "MyCustomAuthTypeName"), authTicket.UserData.Split(','));

        //We are officially 'authenticated' at this point but not neccessarily 'authorized'
    }
    else
    {
        throw new HttpException("Cookieless Forms Authentication is not supported for this application.");

    }
}

答案 4 :(得分:0)

在创建FormsAuthenticationTicket时,您将isPersistent参数设置为false。此参数应设置为true。