代码之家  ›  专栏  ›  技术社区  ›  Andre Pena

为什么我的表单验证票证过期这么快?

  •  10
  • Andre Pena  · 技术社区  · 15 年前

    FormsAuthenticationTicket 在一年内到期,但实际上在一小时左右到期。我不明白为什么。

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

    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;
        }
    }
    

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

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

    编辑

    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;
    }
    
    5 回复  |  直到 13 年前
        1
  •  7
  •   Jernej Novak John Wu    9 年前

    <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
  •   matt-dot-net    15 年前

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

        3
  •  1
  •   shookdiesel    15 年前

    http://support.microsoft.com/kb/910439/

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

        4
  •  0
  •   Daniel Dyson    15 年前

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

        5
  •  0
  •   Damien Dennehy    15 年前

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

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

    推荐文章