views:

349

answers:

1

I want to have functionality on my application that lets a user check off that they wish to stay logged indefinitely (arbitrarily setting the cookie expiration at 3 months from NOW).

The code I have for dealing with this is

private static HttpCookie GetFormsAuthenticationCookie(string userNameResponse, 
                                                        bool persistCookie)
{            
    var cookie = FormsAuthentication.GetAuthCookie(userNameResponse, persistCookie);

    if (persistCookie)
        cookie.Expires = DateTime.Now.AddMonths(3);

    return cookie;
}

private void LoginUser(string userNameResponse, bool PersistCookie)
{
    Response.Cookies.Add(GetFormsAuthenticationCookie(userNameResponse, PersistCookie));

    string navigateAfterUrl = FormsAuthentication.GetRedirectUrl(userNameResponse,
                                                                 PersistCookie);

    Response.Redirect(navigateAfterUrl);
}

However at some point later when I return to the site I need to login again. I have verified that the cookie comes back with my expiration date and that it is not set as a session cookie (also tested with closing/reopening browser and cookie still exists). My one thought is that it has something to do with when ASP.NET expires the session.

I have a specific machine key setup in my web.config so shouldn't the same cookie work if IIS gets restarted etc? Does anyone have any suggestions on what could either be causing this or atleast on how to trace this further since I can't think of anything else to do.

+1  A: 

When you call the GetAuthCookie method a FormsAuthenticationTicket is created with a timeout given by the Timeout property in web.config. So be sure to set it properly:

<authentication mode="Forms">
  <forms
    loginUrl="/someloginUrl"
    requireSSL="true"
    protection="All"
    // This is the setting you are looking for! (it's in seconds)
    timeout="120"
    domain="example.com"
    slidingExpiration="false"
    name="cookieName" />
</authentication>

Once the ticket is encrypted it is used as a value for the cookie. When you set the Expires property of your cookie to a given value this indicates that it will be persisted on the client computer for the given period. Then on every request ASP.NET runtime will check the presence of the cookie, will try to decrypt the value and obtain the ticket. Next it will check if the ticket is still valid by using the Timeout property, so if you have a small timeout, no matter that your cookie is still transmitted, the ticket is no longer valid and the authentication will fail.

Darin Dimitrov
So what is the trade off that comes with if I set the timeout to 3*30*24*60? That a user that doesn't choose to remain logged in will never ever be idled off our site until they close the browser and the session cookie is removed?
Chris Marisic
Even if the user closes the browser, if you setup a persistent cookie (Expires property), then he won't be logged off. But if you call the `FormsAuthentication.SignOut` method the cookie will be invalidated.
Darin Dimitrov
I was referring to a user that chooses to not stay logged in that the cookie isn't set to be persistent.
Chris Marisic
My primary concern would be a user logs onto the site from a public computer, does some stuff and walks away. Normally they'd get logged out after a period of inactivity but setting the ticket timeout to be 3months would end that wouldn't it?
Chris Marisic
Yes it would end that if you are using persistent cookies.
Darin Dimitrov