views:

46

answers:

3

I have a site that uses FormsAuthentication and yes, the name of the cookie is .ASPAUX :)

I can log in perfectly. The server creates a forms authentication ticket, packs it in a cookie, properly determines the expiration time (1 year ahead) and sends it to the client.

For some reason, after some time, even though the cookie is there yet (I can see it with FireCookies) HttpContext.Current.Request.IsAuthenticated becomes false at the server. It's as if the cookie couldn't be validated.

The problem is: Why would that happen? How can I debug why the cookie suddenly becomes invalid without expiring?

EDIT

Here's the login method:

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

And the web.config:

<authentication mode="Forms">
            <forms loginUrl="~/Login.aspx" timeout="2880" slidingExpiration="true"/>
        </authentication>
A: 

Look into expiry of Forms Authentication Tickets as well as cookies. The expiration dates of the two are independent of one another.

When you log in, a ticket is created and encrypted and the authentication cookie contains the ticket. It is most likely the expiry of the ticket that causes your session to end.

If you don't set the slidingExpiration attribute in your web.config then, in theory, the authentication cookie timeout is set to a fixed value from your timeout attribute. However, in my experience, it has always been stuck at the default 30 minutes. With the slidingExpiration on, the ticket timeout is supposedly updated on each postback.

Here's a Microsoft knowledgebase article that elaborates

There's also an article explaining the default forms authentication timeout from Scott Guthrie here

Forms Authentication Configuration and Advanced Topics

Neil Fenwick
thank you for your reply. As you can see from my edit, the ticket timeout is properly set for one year and I'm using sliding expiration
Ciwee
there's a possibility that the timeout property set to 2880 is the source of the problem. I've set it to 525600, that's the number of minutes of a year. It's curious: it seems that the expiry date of FormsAuthenticationTicket IS the actual cookie expiry date. But in the other hand, it seems that the web.config timeout property determines whether or not the existing cookie is valid. I'm changing this property and I'll see if it expires. Thanks.
Ciwee
Just checked it. Didnt work. It already expired. I can tell how much minutes it took because the expiration was sliding :(
Ciwee
A: 

A few things I can think of to check:

Do you have multiple domains (including www.domain.com vs domain.com)?

If so, either set the domain in the cookie as domain.com or ensure you always use the same domain

Are you using HTTPS?

If so, make sure you're always accessing the cookie via HTTPS or making sure that Secure is set to false on the HttpCookie (otherwise it's only accessible on HTTPS requests)

Are you writing the cookie from a virtual directory?

If so, the "path" on the cookie might be set and it won't be accessible from outside the path.

Do you have multiple web servers?

If so, make sure your machine key is set to the same value (though that should be throwing an exception)

Richard Szalay
thank you for your reply. The answer is no for all of the above.
Ciwee
+1  A: 

Set static machine keys in your web.config to make sure that the encryption key used in generating your ticket survives an application pool being recycled (or your website being restarted in the ASP.NET web server)?

Also see the Forms Authentication Tickets section of this MSDN library article

Neil Fenwick
Is the DEFAULT behavior of the ticket encryption to INVALIDATE tickets just because the server restarted? Isn't it a little bit odd?
Ciwee
Thanks by the way. I'll give it a try. I don't exactly know how to assign static machine keys but I'll look after it now.
Ciwee
We're close to the solution. Just verified: Restarting the website has no effect, but recycling the Application Pool causes all the forms authentication tickets to expire. I'm going to try the static keys now.
Ciwee
I was able to set static keys and now it's no longer sinsible to the application pool recycle, what's already an advantage. New I'll see if it will expiry.
Ciwee
Hi @Ciwee, its not so much that the ticket encryption intentionally invalidates the tickets. The ticket is encrypted using the MACHINE KEY and the default for that, unless its explicitly specified, is to auto-generate. So that implies it would be a new key every time the app restarted.
Neil Fenwick
It seems that it worked. Thanks a lot!
Ciwee