我正在尝试使用以下代码(在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,问题仍然存在,因此我不认为这是一个大小问题。
感谢您提供的任何见解。
答案 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。