views:

122

answers:

5

I'm using forms authentication in an ASP.NET application. I configure the FormsAuthenticationTicket to expire in 1 year but it actually expires after 1 hour or so. I can't figure out why.

Here is all the code involved in the login process:

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>
...

Is something wrong with my approach? Why is it expiring so fast?

EDIT

Global.asax code:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {


            if (Request.PhysicalPath.EndsWith(".aspx") || Request.PhysicalPath.EndsWith(".axd") || Request.PhysicalPath.EndsWith(".ashx"))
                SecurityManager.SetPrincipal();
        }

SetPrincipal Code:

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;
        }
+1  A: 

I don't see anything wrong with the code. What browser are you using, perhaps it doesn't recognize the expiration date of 1 year? I would look at the response headers with fiddler or some such tool and see what's actually being sent.

matt-dot-net
I get the problem with any browser
Ciwee
and what does the response header look like?
matt-dot-net
I agree that the first place to look is at the raw cookies / traffic. Firefox with the Firebug and Firecookie plugins is one excellent way to scope out the situation (that's how I debugged my issues with forms authentication).
RQDQ
A: 

Can we see more context on how you are using your Login process?

Are you calling FormsAuthentication.RedirectFromLoginPage(), FormsAuthenication.GetAuthCookie(), or FormsAuthentication.SetAuthCookie() anywhere?

Those methods recreate the cookie.

GWB
GWB, thanks for your reply. I made a search and I'm not using any of these methods :(
Ciwee
A: 

The only thing that I can see that is non-standard is that you are passing id.ToString() to the FormsAuthenticationTicket constructor. I usually pass the username in this parameter. Not sure whether this will make a difference, but worth a try.

Daniel Dyson
A: 

Are you using anything else in your application that might cause a timeout? Automatically logging you out if in-proc session states expire for example.

I assume you've got some code in your Global.asax to process the authenticated request too?

Damien Dennehy
I don't think I'm using anything that would cause a timeout. I added more information about the authentication code.
Ciwee
A: 

This might help http://support.microsoft.com/kb/910439/

My guess is that the cookie is expiring before the ticket. The above article shows you ways to debug to see if that is indeed the case.