【发布时间】:2014-08-03 13:19:03
【问题描述】:
我正在使用 FormsAuthentication 编写一个 ASP.net MVC 5 应用程序。我使用FormsAuthentication.SetAuthCookie(user.Email, model.RememberMe) 完成了所有工作并正常工作。
但是,我想创建一个自定义票证,以便可以在票证的 UserData 字段中存储一些额外信息。这就是我创建票证并将其存储在 cookie 中的方式:
var ticket = new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.Minutes), model.RememberMe, user.AuthToken);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Domain = FormsAuthentication.CookieDomain, Path = FormsAuthentication.FormsCookiePath, HttpOnly = true, Secure = FormsAuthentication.RequireSSL };
HttpContext.Response.Cookies.Add(cookie);
这将创建一个加密票并将其发送到浏览器。我已经使用开发人员工具和 Fiddler 验证了该票证存在于浏览器中,并且它会在后续请求中发送回服务器。
但身份验证现在已被破坏。此外,cookie 在Application_AuthenticateRequest 或Application_PostAuthenticateRequest 事件中不可用。当我使用调试器探索Context.Request.Cookies 时,它不在列表中。
奇怪的是,如果我退回到管道并在Application_BeginRequest 中检查它,cookie 确实存在:
void Application_BeginRequest(object sender, EventArgs e)
{
// Auth cookie exists in the collection here! Ticket decrypts successfully
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null)
return;
var encTicket = authCookie.Value;
var ticket = FormsAuthentication.Decrypt(encTicket);
}
void Application_AuthenticateRequest(object sender, EventArgs e)
{
// Auth cookie missing from the cookies collection here!
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null)
return;
var encTicket = authCookie.Value;
var ticket = FormsAuthentication.Decrypt(encTicket);
using (var db = new BadgerContext())
{
var user = db.Users.OfType<RegisteredUser>().FirstOrDefault(x => x.UserName == ticket.Name);
if (ticket.UserData != user.AuthToken)
{
FormsAuthentication.SignOut();
Response.Redirect(FormsAuthentication.DefaultUrl);
}
}
}
因此,在BeginRequest 之后但在AuthenticateRequest 之前,似乎有些东西正在将我的自定义 FormsAuthenticationTicket 从 cookie 中剥离出来。不幸的是,这完全破坏了网站上的身份验证。
在我创建自定义票证时,有什么想法会导致这种行为吗?我的 cookie 创建有问题吗?
【问题讨论】:
-
可能需要在创建 cookie 的位置设置
cookie.Expires。假设我们正在谈论单个浏览器会话,我认为这没有必要,但这是唯一让我感到震惊的事情。 -
FormsAuthentication.Timeout.Minutes的值是多少?除非经过验证,否则 cookie 不会存在于AuthenticateRequest中。确保 cookie 不会提前过期。 -
此外,虽然一点也不令人满意,但如果您可以在
BeginRequest中获取 cookie,您可能会使用Context.Items来存储信息以供稍后在管道中使用。 -
Rowan,我单步执行了创建票证的代码,
FormsAuthentication.Timeout.Minutes为 0,导致票证立即到期。我不得不改用FormsAuthentication.Timeout.TotalMinutes,一切又开始正常工作。添加为答案,我会接受。
标签: c# asp.net asp.net-mvc forms-authentication