2

我正在尝试使用以下代码(在 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,问题仍然存在,所以我认为这不是大小问题。

感谢您提供的任何见解。

4

5 回答 5

3

cookie 的最大大小为 4096 字节。如果它高于此 cookie 将不会被保存。

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

int cookieSize = System.Text.UTF8Encoding.UTF8.GetByteCount(faCookie.Values.ToString());
于 2012-10-17T15:39:58.637 回答
1

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

于 2012-06-29T17:28:36.043 回答
1

在编写 cookie 的代码中,您不能将 null 传递给带有加密 cookie 的 userData 参数。IsPersistent 为 false 很好。

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

执行以下操作:在我的示例中,您可以将 userData.ToString() 替换为空字符串。只是不要给它一个空值!那应该可以解决您的问题。

 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.");

    }
}
于 2014-03-03T20:20:20.463 回答
1

尽管您的身份验证票证设置为持久性并具有过期日期,但实际的 cookie 没有。

在创建 cookie 时添加如下内容:

var faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
                   {
                       Expires = ticket.Expiration
                   };
于 2013-10-26T12:33:43.070 回答
0

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

于 2013-04-07T19:59:18.127 回答