ASP.net MVC FormsAuthentication cookie missing

4
我正在编写一个使用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 进行验证,证实该票证存在于浏览器中,并在后续请求中发送回服务器。
但是,身份验证现在已经破坏了。此外,在 Application_AuthenticateRequestApplication_PostAuthenticateRequest 事件中,cookie 不可用。当我使用调试器来探索 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);
        }
    }
}

看起来有些东西在BeginRequestAuthenticateRequest之间从我的自定义FormsAuthenticationTicket中剥离了cookie。不幸的是,这会完全破坏网站上的身份验证。

创建自定义票证时,任何想法是什么导致了这种行为?我在cookie创建方面做错了什么吗?


可能需要在创建cookie时设置cookie.Expires。我认为这不是必需的,假设我们正在讨论单个浏览器会话,但这是唯一引起我的注意的问题。 - jandersen
3
FormsAuthentication.Timeout.Minutes 的值是多少?除非验证过,否则在 AuthenticateRequest 中没有该 cookie。确保该 cookie 没有提前失效。 - Rowan Freeman
此外,虽然并不完美,但如果您可以在 BeginRequest 中获取 cookie,则可以使用 Context.Items 存储信息以供后续流程使用。 - jandersen
Rowan,我逐步检查了创建票证的代码,发现FormsAuthentication.Timeout.Minutes为0,导致票证立即过期。我不得不使用FormsAuthentication.Timeout.TotalMinutes,然后一切都正常工作了。请将其添加为答案,我会接受。 - Sam
2个回答

8
请在 .config 文件中检查 system.web 节点内的 httpRuntime 标记。
与主网站相同,如下所示: <httpRuntime targetFramework="4.5" />

这对我来说实际上解决了问题。票证没有过期,但仍未被收集。确保我的两个项目都在web.config中有这个后,它就起作用了!非常感谢! - Ian Schmitz

0

Rowan建议我查看FormsAuthentication.Timeout.Minutes的值。经过调查,这个值总是返回0。这导致票证立即过期。我不得不使用FormsAuthentication.Timeout.TotalMinutes,然后一切都开始正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接