【问题标题】:Why are my forms authentication tickets expiring so fast?为什么我的表单身份验证票过期如此之快?
【发布时间】:2010-07-03 03:26:13
【问题描述】:

我在 ASP.NET 应用程序中使用表单身份验证。我将FormsAuthenticationTicket 配置为在 1 年内到期,但它实际上在 1 小时左右后到期。我不知道为什么。

以下是登录过程中涉及的所有代码:

public static bool Login(int id)
{
    try
    {
        string securityToken = UserHelper.AuthenticateUser(id);

        DateTime expiryDate = DateTime.Now.AddYears(1);
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
             1, id.ToString(), DateTime.Now, expiryDate, true,
             securityToken, FormsAuthentication.FormsCookiePath);

        string encryptedTicket = FormsAuthentication.Encrypt(ticket);
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
        cookie.Expires = expiryDate;

        HttpContext.Current.Response.Cookies.Add(cookie);

        return true;
    }
    catch
    {
        return false;
    }
}

Web.config:

<system.web>
    <machineKey validationKey="AutoGenerate"
    decryptionKey="AutoGenerate" validation="SHA1" />
    <compilation debug="true">
    <authentication mode="Forms">
        <forms loginUrl="~/Login.aspx" timeout="2880"/>
    </authentication>
...

我的方法有问题吗?为什么过期这么快?

编辑

Global.asax 代码:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (Request.PhysicalPath.EndsWith(".aspx") || Request.PhysicalPath.EndsWith(".axd") || Request.PhysicalPath.EndsWith(".ashx"))
        SecurityManager.SetPrincipal();
}

设置主体代码:

public static void SetPrincipal()
{
    ILivrePrincipal principal = null;
    FormsIdentity identity;
    UrlParameters urlParameters = UrlParametersHelper.GetUrlParameters(HttpContext.Current.Request);

    if (HttpContext.Current.Request.IsAuthenticated)
    {
        identity = (FormsIdentity)HttpContext.Current.User.Identity;

        User userProfile;
        urlParameters.SecurityToken = (((FormsIdentity)identity).Ticket).UserData;
        try
        {
            userProfile = UserHelper.GetUser(urlParameters.SecurityToken);
            UserHelper.UpdateLastActiveOn(userProfile);
            principal = new AuthenticatedPrincipal(identity, userProfile);
        }
        catch
        {
            //TODO: Log an exception
            FormsAuthentication.SignOut();
            principal = new AnonymousPrincipal(new GuestIdentity(), UserHelper.GetUser(null));
        }
    }
    else
    {
        principal = new AnonymousPrincipal(new GuestIdentity(), UserHelper.GetUser(null));
    }

    HttpContext.Current.User = principal;
}

【问题讨论】:

  • 为什么你有timeout="2880"(指定2天)?
  • @Gabe 谢谢。我同意你。这是一个错误,但仍然无法解释为什么我的登录会话会在大约一个小时后到期。

标签: c# .net asp.net authentication forms-authentication


【解决方案1】:

这是你的问题。

<machineKey validationKey="AutoGenerate" 
            decryptionKey="AutoGenerate" 
            validation="SHA1"/>

每次应用程序池回收时,ASP 都会生成一个新的机器密钥。这可以合理地每小时发生一次。

机器密钥用于加密和解密您的 FormsAuthentication cookie。如果它发生变化,您浏览器上的 cookie 将不再有用。因此系统会将您视为从未登录过。

尝试生成一个静态密钥并将其添加到配置文件中。应该看起来像这样:

<machineKey  
    validationKey="21F090935F6E49C2C797F69(snip)F1B72A7F0A281B"          
    decryptionKey="ABAA84D7EC4BB56D75D(snip)B8BF91CFCD64568A145BE59719F"
    validation="SHA1"
    decryption="AES"
/>

为自己生成一个密钥here

【讨论】:

    【解决方案2】:

    我看不出代码有什么问题。您使用的是什么浏览器,可能无法识别 1 年的到期日期?我会使用 fiddler 或类似工具查看响应标头,看看实际发送的是什么。

    【讨论】:

    • 任何浏览器都有问题
    • 响应头是什么样的?
    • 我同意首先查看原始 cookie / 流量。带有 Firebug 和 Firecookie 插件的 Firefox 是确定情况的一种极好的方法(这就是我调试表单身份验证问题的方式)。
    【解决方案3】:

    这可能有助于http://support.microsoft.com/kb/910439/

    我的猜测是 cookie 在出票之前就过期了。上面的文章向您展示了调试方法,看看是否确实如此。

    【讨论】:

      【解决方案4】:

      我能看到的唯一非标准是您将 id.ToString() 传递给 FormsAuthenticationTicket 构造函数。我通常在这个参数中传递用户名。不确定这是否会有所作为,但值得一试。

      【讨论】:

        【解决方案5】:

        您是否在应用程序中使用了其他可能导致超时的内容? 例如,如果进程内会话状态过期,则自动将您注销。

        我假设您的 Global.asax 中也有一些代码来处理经过身份验证的请求?

        【讨论】:

        • 我认为我没有使用任何会导致超时的东西。我添加了有关身份验证代码的更多信息。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 2010-10-12
        • 2015-01-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多