12

表单身份验证票过期的另一个问题。我需要使用滑动过期设置为真。我已经阅读了论坛并理解了精度损失的问题,即只有在过期时间的一半之后发出请求时才会更新票证。

问题:在我的webconfig中,我有以下内容:

    <authentication mode="Forms">
        <forms timeout="20" name="SqlAuthCookie" protection="All" slidingExpiration="true" />
    </authentication>
    <sessionState timeout="20" />
    <authorization>

只有在 20 分钟间隔内没有请求时,用户才必须注销并重定向到 login.aspx。问题是用户正在发出请求,但仍然被抛出到登录页面。这不应该发生。我想做的是为每个请求手动重置 SqlAuthCookie 。

下面是我的代码。它在 context.AcquireRequestState 上调用。

    void context_AcquireRequestState(object sender, EventArgs e)
    {
        HttpContext ctx = HttpContext.Current;
        ResetAuthCookie(ctx);
     }

            private void ResetAuthCookie(HttpContext ctx)
    {
        HttpCookie authCookie = ctx.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie == null)
            return;

        FormsAuthenticationTicket ticketOld = FormsAuthentication.Decrypt(authCookie.Value);
        if (ticketOld == null)
            return;

        if (ticketOld.Expired)
            return;

        FormsAuthenticationTicket ticketNew = null;
        if (FormsAuthentication.SlidingExpiration)
           ticketNew = FormsAuthentication.RenewTicketIfOld(ticketOld);

        if (ticketNew != ticketOld)
            StoreNewCookie(ticketNew, authCookie, ctx);
    }

    private void StoreNewCookie(FormsAuthenticationTicket ticketNew, HttpCookie authCookie, HttpContext ctx)
    {
        string hash = FormsAuthentication.Encrypt(ticketNew);
        if (ticketNew.IsPersistent)
            authCookie.Expires = ticketNew.Expiration;

        authCookie.Value = hash;
        authCookie.HttpOnly = true;

        ctx.Response.Cookies.Add(authCookie);
    }

我的问题是:

  1. 在每个请求上重置 cookie 是错误的还是可接受的解决方案?
  2. 为什么它仍然不起作用?似乎新票永远不会更新。
  3. 是否还有其他可能的原因,因为用户的表单身份验证过早过期,我应该调查?

谢谢, 问候,

4

1 回答 1

15

A forms authentication cookie only renews itself after half it's expiration time has passed.

From Microsoft:

If the Web page is accessed before half of the expiration time passes, the ticket expiration time will not be reset. For example, if any Web page is accessed again at 5:04 00:00:00 PM, the cookies and ticket timeout period will not be reset.

To prevent compromised performance, and to avoid multiple browser warnings for users that have cookie warnings turned on, the cookie is updated when more than half the specified time has elapsed.

This may be your issue. If your clients access your site at the 9 minute mark and don't access it again for 10 minutes they'll be timed out. This occurs even though you have your session timeout set to 20 minutes.

Manually renewing your ticket like you're doing isn't necessary. You just need sliding expiration enabled. If the 'half the specific time' rule doesn't work for you then you'll have to look at other solutions.

于 2012-10-11T20:22:01.157 回答