locked
forms authentication timeout and persistent cookies RRS feed

  • Question

  • User470202672 posted
    I was always told that it was wise to minimise the forms authentication
    timeout for both performance and security reasons (the documentation also
    recommends this
    http://technet2.microsoft.com/WindowsServer/en/Library/f69977f1-1415-45f2-9e51-c1dac4aa03b21033.mspx?mfr=true
    "You might consider changing the timeout value to a shorter amount of time,
    to shorten the session lifetime and to reduce the possibility of cookie
    replay attacks.").

    However in asp.net 2.0, persistent cookies no longer have a hardcoded
    timeout of 50 years (thanks for that), but instead take their timeout from
    the timeout attribute on the forms authentcation node. I'm not sure how the
    two gel together, as it seems I can either choose performance and better
    security or else persistent cookies. At present for a few asp.net 2.0
    websites I'm having to set timeout's of days/weeks, and I'm not completely
    comfortable with this. It seems to me that MS should have provided two
    settings, one specific to forms authentication, and one to persistent
    cookies.

    Am I picking up something wrong here, as at the minute I think to get around
    this limitation, I'm going to have to extend the forms authentication timout
    for persistent cookies via code rather than relying on the timeout value.

    Thanks,
    Cathal

     
    Thursday, July 20, 2006 7:14 PM

All replies

  • User-1634877164 posted

    Hi Cathal,

    I talk a little about how to configure it in this blog post here: http://weblogs.asp.net/scottgu/archive/2005/11/08/430011.aspx

    Hope this helps,

    Scott

    Friday, July 21, 2006 4:35 AM
  • User470202672 posted

    Thanks for the post Scott,  but I don't think I'm explaining my scenario very well. I'm not so worried about persistent cookies (in fact I prefer that I have control over the timeout now), my concern is that the in-memory authetication and persistent authentication storage timeout is the same i.e.

    Previously in asp.net 1.1 if I set my forms authentication timeout to 15 minutes, when a user logged in they would be authenticated for that period and continue to be authenticated as long as they did not take more than that period between page refreshes. The in-memory authentication would also automatically be removed if I either closed the browser, or navigated to another website (the browser would remove the the in-memory auth cookie after the forms authentication timeout expired). If I decided to allow my users to selected to be to use persistent cookies (i.e. via a "remember me" dialog), they got a 50 year long cookie, which whilst IMHO was very insecure (giving hackers a much larger window for cookie replay attacks etc.), did function as my users required.

    Now in asp.net 2.0 if I set my forms authentication timeout to 15 minutes, I still have the same behaviour for users who log on everytime, but persistent cookies aren't really persistent. To achieve persistent cookies  I need to increase the timeout to something much larger e.g. 1440 to cover 1 day, but it seems to me that this then means that it impacts for users with in-memory authentication i.e. if I browse to the site, I get a temporary cookie with a timeout of 24 hours - now if I navigate away to another site (without closing the browser first) my auth cookie will live for a substantially larger amount of time meaning that if someone can gain access to my cookie (e.g. via an XSS attack) or else if i walk away from the browser and they use the back button, they have a much greater window of opportunity.

    To me it seems that in trying to fix the security issue with a hardcoded timeout for persistent cookies in 1.1, by tying the values of transient and persistent cookies together in one parameter, Microsoft have accidentally weakened non-persistent authentication for websites that require the option to persist cookies. Obviously I can override the default behaviour by setting my own cookie expiration in code, but it does seem to me that this is a weakness in the available configuration settings.

    Cathal

    Friday, July 21, 2006 10:29 AM
  • User-1261216960 posted
    I agree with Cathal.  The hard coded persistent cookie timeout in v1.x has been "fixed" by making it use the timeout value set in web.config.  The problem is that the non-persistent authentication time-out is controlled by this same setting.  What this does is effectively break the "remember me" checkbox on the login control if you let the timeout setting be the default of 30 minutes.  And if you want to make the "remember me" checkbox actually remember the user for a useful amount of time, you have to change the timeout value -- which changes the timeout value for non-persistent authentication as well leading to security issues as Cathal outlined.

    It should be two separate settings in web.config.  I don't know why it wasn't made that way to begin with.
    Friday, August 4, 2006 11:52 AM
  • User-131615530 posted
    This is a potential work-around for use with cookie persistance:

    protected void Login1_LoggedIn(object sender, EventArgs e)
    {
        if (Response.Cookies.Count > 0)
        {
           foreach (string s in Response.Cookies.AllKeys)
           {
              if (s == FormsAuthentication.FormsCookieName)
              {
                 if (Login1.RememberMeSet == true)
                 {
                    // change the value to increase the cookies expiration by
                    Response.Cookies[s].Expires = DateTime.Now.AddYears(1);
                 }
              }
           }
        }
    }
    Wednesday, August 9, 2006 12:20 PM
  • User2112754610 posted

    The above code will not work.  It may set the cookie to be a year long but the forms authentication ticket itself will maintain the 30 minute (or whatever the Web.config setting is) expiration.

    The length of the expiration of the cookie doesn't matter, the forms authentication ticket has its own expiration... so even tho the cookie expired in 10 days, the ticket by default has a 30 minute expiration.

    The "remember me" check changes the cookie from a session cookie to a persistant cookie.

    I have changed the forms authentication timeout to 43200 (30 days). This means that if someone is logged in without clicking the remember me button... their session will last as long as they have the browser window open with up to 30 days of idle time. (If they kept it open for 30 days without requesting a page, they would have to log back in when they sent another request). If they close the browser, they will have to log back in.

    If they clicked "Remember Me" ,they can come back to the site after having closed the browser and not have to log back in, up to 30 days after the last time they were on the site.

    The 50 year thing is right out: http://weblogs.asp.net/scottgu/archive/2005/11/08/430011.aspx - the documentation (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.login.remembermeset(VS.80).aspx ) is wrong with what Scott Gutherman says as well as what i see in my experiments.

     I do think its unfortuneate that the persistant and session timeouts are linked.  Someone who doesn't click the "Remember Me" may want themselves to be logged out after a certain amount of idle time if they walk away from the machine but leave the browser open.  But as Scott points out in the comments from the above link, you could make your own cookie that expires if you want such a thing.

    One more thing:
    Session timeout separate... so after some amount of idle time on a single session, all session data will be lost and all session data will be lost when the browser is closed. So session data cannot be set at login time ONLY. Functions using Session data need to expect that session could expire without the user logging out.  (If you set the Authentication timeout to be something longer than the session time out).
    Thursday, March 8, 2007 6:11 PM
  • User799536816 posted

    [:'(]

    This is a potential work-around for use with cookie persistance:

    protected void Login1_LoggedIn(object sender, EventArgs e)
    {
        if (Response.Cookies.Count > 0)
        {
           foreach (string s in Response.Cookies.AllKeys)
           {
              if (s == FormsAuthentication.FormsCookieName)
              {
                 if (Login1.RememberMeSet == true)
                 {
                    // change the value to increase the cookies expiration by
                    Response.Cookies[s].Expires = DateTime.Now.AddYears(1);
                 }
              }
           }
        }
    }

     

    I have been facing this problem and have been looking into it and its possible solutions. This code definitely doesn't work. The funny thing is on firefox when I try to check the cookie information, my cookie "expires" value shows as a week from now (I have set a key in web.config appsettings and picking up the timeout value from there which is a week) but it will still take the timeout of forms [:'(] 

    How am I supposed to handle persistent and non-persistent logins differently and make a new cookie and all? Please enlighten me. 

     

    Thanks in advance

    Sanchita 

     

    P.S. - I am using DNN but that shouldn't be a cause of concern 

    Tuesday, April 17, 2007 2:28 PM
  • User799536816 posted

    [:'(]

    This is a potential work-around for use with cookie persistance:

    protected void Login1_LoggedIn(object sender, EventArgs e)
    {
        if (Response.Cookies.Count > 0)
        {
           foreach (string s in Response.Cookies.AllKeys)
           {
              if (s == FormsAuthentication.FormsCookieName)
              {
                 if (Login1.RememberMeSet == true)
                 {
                    // change the value to increase the cookies expiration by
                    Response.Cookies[s].Expires = DateTime.Now.AddYears(1);
                 }
              }
           }
        }
    }

     

    I have been facing this problem and have been looking into it and its possible solutions. This code definitely doesn't work. The funny thing is on firefox when I try to check the cookie information, my cookie "expires" value shows as a week from now (I have set a key in web.config appsettings and picking up the timeout value from there which is a week) but it will still take the timeout of forms [:'(] 

    How am I supposed to handle persistent and non-persistent logins differently and make a new cookie and all? Please enlighten me. 

     

    Thanks in advance

    Sanchita 

     

    P.S. - I am using DNN but that shouldn't be a cause of concern 

    Tuesday, April 17, 2007 2:29 PM
  • User2112754610 posted

    the issue is that the forms authentication ticket has a separate expiration date within its data that is separate from the cookie's expiration date. 

    Setting the web.config

    <!-- Forms or Windows authentication -->

    <authentication mode="Forms">

    <forms name=".DOTNETNUKE" protection="All" timeout="43200" cookieless="UseCookies"/>

    </authentication>

    like above  will enable people who select the "remember me" to come back in a new browser session up to 30 days in the future.

    people who don't select remember me will not be logged out as long as they keep their current browser window open.

    Its possible you could adjust the forms authenication ticket and have its expiration and the cookie expiration change based on the "remember me", but I ask why?

    I don't really want my users to have to log in again after they have gone to lunch, and if they are at a public terminal, as long as that session ends or they close the browser, there isn't a good chance that someone else will be able to log in as them at the site.   I don't really like the way MS linked this together so closely, but when it comes down to it, it wasn't that big a deal for the non-persistant side if they were never forced to log out. (until they close the browser).

    Wednesday, April 18, 2007 10:01 AM
  • User799536816 posted

    the issue is that the forms authentication ticket has a separate expiration date within its data that is separate from the cookie's expiration date. 

    Setting the web.config

    <!-- Forms or Windows authentication -->

    <authentication mode="Forms">

    <forms name=".DOTNETNUKE" protection="All" timeout="43200" cookieless="UseCookies"/>

    </authentication>

     I know about this configuration but I dont want to set a general timeout for both users with persistent and non-persistent cookies.
     


    like above  will enable people who select the "remember me" to come back in a new browser session up to 30 days in the future.

    people who don't select remember me will not be logged out as long as they keep their current browser window open.

    Its possible you could adjust the forms authenication ticket and have its expiration and the cookie expiration change based on the "remember me", but I ask why?

    I don't really want my users to have to log in again after they have gone to lunch, and if they are at a public terminal, as long as that session ends or they close the browser, there isn't a good chance that someone else will be able to log in as them at the site.   I don't really like the way MS linked this together so closely, but when it comes down to it, it wasn't that big a deal for the non-persistant side if they were never forced to log out. (until they close the browser).

    I want to seperate my users into one's who want to remain logged on as long as their browser is open and other's who want to be logged out as soon as their session is over.

    If you could please guide me on how can I implement adjusting the forms authentication ticket and set its expiration cos I had tried a code for this but it didn't turn out to work as I expected.

     

    Thanks,

    Sanchita 

    Wednesday, April 18, 2007 12:24 PM
  • User2112754610 posted

    I want to seperate my users into one's who want to remain logged on as long as their browser is open and other's who want to be logged out as soon as their session is over.

    If you could please guide me on how can I implement adjusting the forms authentication ticket and set its expiration cos I had tried a code for this but it didn't turn out to work as I expected.

    I haven't modfied the forms authentication ticket in this manner before so I don't have any code to send you.  You will probably need to override where the login control is creating the ticket.

     The user categories you are saying aren't categories that are controled by forms authentication.  Forms authentication uses cookies which are in 2 categories: session and persistant.

    Session (cookie session, not ASP Session) is that the cookie stays around only as long as the browser stays open or the cookie's expire time hits (whichever happens first).  Forms authentication keeps pushing the cookie's expire time out as long as the user is active.

    Persistant is a cookie that is written to the users disk and will be available on the next browser session (after all browser windows are closed, or the machine is rebooted, whatever) and only expires when the cookie is marked to expire.  This is what is used by default when someone clicks the "Remember Me" check box on login controls.

    The two categories you are asking for aren't really supported by the forms authentication ticket system.  You would probably need to make the login control either store a variable in the ASP session object, or store the variable in a non-persistant cookie that has a far off expiration date, depending on whatever mechanism you are using to divide your users into the categories.

    Wednesday, April 18, 2007 3:40 PM
  • User-1297451741 posted

     I had the same problem and i solved my problem by generating AuthTicket and redirect user by myself

    here is my code that work with diffrent timout setting for cookie  and session :

     

     

                if (Login1.RememberMeSet)
                {
                    FormsAuthenticationTicket authTicket = new
                        FormsAuthenticationTicket(user.Id.ToString(), true, cookietimeout);
                    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    cookie.Expires = authTicket.Expiration; 
                    HttpContext.Current.Response.Cookies.Set(cookie);
                    Response.Redirect(FormsAuthentication.GetRedirectUrl(user.Id.ToString(),false), true);
                }
                else
                {
                    FormsAuthentication.SetAuthCookie(user.Id.ToString(), false);
                    FormsAuthentication.RedirectFromLoginPage(user.Id.ToString(), false);
                }
    
     

    as you can see,

    I use Response.Redirect instead of FormsAuthentication.RedirectFromLoginPage and Instead of SetAuthCookie, I generate the authTicket and add auth Cookie to Response.Cookies by myself

     

    Monday, December 10, 2007 4:46 AM
  • User1913889050 posted

    pooya.m, this is the first bit of information I've found about generating a separate AuthTicket, and I confess I am not seeing the whole picture of your solution.  Is this for roles authentication?  Does it work with Forms authentication?

    I keep getting an error on cookieTimeout, and cannot set this attribute in the web.config.

    Could you possibly explain this a little more?

    Tinker

    Thursday, February 7, 2008 11:44 AM
  • User260221095 posted

    Thanks Martin,ur post is really useful , but when using FormsAuthentication.SignOut() Method...both persistent and in-memoey cookies are expired


    Saturday, May 2, 2009 8:47 PM
  • User310830513 posted

    Hi pooya.m,

    I had similar problem and got resolved. thanks for the nice post.


    Thanks 

    Anant Ingle

    Thursday, December 17, 2009 4:24 AM
  • User-2074858223 posted
    I have been looking for this solution you gave here. Please any example you Can give on this?
    Thursday, March 16, 2017 6:07 PM