FormsAuthenticationTicket.Expiration value changing

Last post 04-07-2008 5:53 PM by sschack. 17 replies.

Sort Posts:

  • FormsAuthenticationTicket.Expiration value changing

    10-28-2006, 11:46 PM
    • Loading...
    • MikeOtown
    • Joined on 01-05-2005, 10:12 AM
    • Posts 33

    I am creating a FormsAuthenticationTicket and specifying the timout to be different than the value in web.config.  It works fine until the user gets to another page and somehow the FormsAuthenticationTicket.Expiration in the cookie is changed to reflect the timeout in the web.config.

     Here is the code in Login.asp.cs:

    FormsAuthenticationTicket authTicket = new

    FormsAuthenticationTicket(Login1.UserName,

    Login1.RememberMeSet, iMinutes); // set Expiration

     

    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

    HttpCookie authCookie = new HttpCookie(

    FormsAuthentication.FormsCookieName, encryptedTicket);

    authCookie.Expires = authTicket.Expiration;

    HttpContext.Current.Response.Cookies.Add(authCookie);

    e.Authenticated = true; // authTicket.Expiration is correct here

    And here is the code in the following page Load event:

    FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(Request.Cookies[".ASPXAUTH"].Value);

    Response.Write("fat.expires=" + fat.Expiration); // expiration ends up as 30 minutes from login here

  • Re: FormsAuthenticationTicket.Expiration value changing

    10-29-2006, 1:42 AM
    Answer
    • Loading...
    • vivek_iit
    • Joined on 06-18-2006, 6:13 PM
    • New Delhi
    • Posts 3,072
    • TrustedFriends-MVPs

    Hi,

    I blogged about this strange behavior in ASP.NET 2.0 recently:

    http://geekswithblogs.net/vivek/archive/2006/10/13/93956.aspx

    I think the functionality has changed and has "crippled" ASP.NET.

    Let me know what you think.

    Vivek

    MVP, ASP.NET || My Website || Blog || Articles

    Please mark the most helpful reply/replies as "Answer".
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-29-2006, 8:42 AM
    • Loading...
    • MikeOtown
    • Joined on 01-05-2005, 10:12 AM
    • Posts 33
    Yes, it looks like the ability to set the timeout value of a FormsAuthenticationTicket in ASP .NET 2.0 is broken.  I haven't seen any other posts about this besides yours.  Microsoft - please acknowledge this issue!!  I wasted hours trying to get this to work.  Releasing a fix would be nice also.
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-30-2006, 4:03 PM
    • Loading...
    • sschack
    • Joined on 09-16-2003, 12:06 PM
    • Posts 607
    • AspNetTeam
      Moderator

    From the post I'm not sure if the sample code is being used inside of the Login control or not.  I did try the following code in just a plain .aspx page used for login:

                //Manual cookie issuance
                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(txtUserId.Text, false, 200); //hardcoded 200 minute duration
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                HttpContext.Current.Response.Cookies.Add(authCookie);
                Response.Redirect("default.aspx"); 

     And then in default.aspx writing out the expiration time:

            FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(Request.Cookies[".ASPXAUTH"].Value);
            Response.Write("fat.expires=" + fat.Expiration);

     This is returning the correct expiration as set on the login page.

    However, if you are attempting to set the cookie from inside of the Login control's Authenticate event, this event is too early to be setting the cookie manually.  The login control event sequence looks like:

            Raises the Authenticate event --->  Login control sets the cookie with a call to SetAuthCookie -->  Raises the LoggedIn event

    To manually control the cookie expiration and cookie issuance, put the cookie code in the LoggedIn event.  I would recommend first removing the cookie set by the Login control (HttpContext.Current.Response.Cookies.Remove), and then re-issuing the cookie manually.

    One other quick note:  you should only set the cookie's expiration property if the user indicated they wanted a persistent cookie.  The code shown in the post is always setting the HttpCookie's expiration date, which has the effect of always making the cookie persistent.

    -Stefan
    ----------------------------------------------------------
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-30-2006, 4:03 PM
    • Loading...
    • sschack
    • Joined on 09-16-2003, 12:06 PM
    • Posts 607
    • AspNetTeam
      Moderator

    From the post I'm not sure if the sample code is being used inside of the Login control or not.  I did try the following code in just a plain .aspx page used for login:

                //Manual cookie issuance
                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(txtUserId.Text, false, 200); //hardcoded 200 minute duration
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                HttpContext.Current.Response.Cookies.Add(authCookie);
                Response.Redirect("default.aspx"); 

     And then in default.aspx writing out the expiration time:

            FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(Request.Cookies[".ASPXAUTH"].Value);
            Response.Write("fat.expires=" + fat.Expiration);

     This is returning the correct expiration as set on the login page.

    However, if you are attempting to set the cookie from inside of the Login control's Authenticate event, this event is too early to be setting the cookie manually.  The login control event sequence looks like:

            Raises the Authenticate event --->  Login control sets the cookie with a call to SetAuthCookie -->  Raises the LoggedIn event

    To manually control the cookie expiration and cookie issuance, put the cookie code in the LoggedIn event.  I would recommend first removing the cookie set by the Login control (HttpContext.Current.Response.Cookies.Remove), and then re-issuing the cookie manually.

    One other quick note:  you should only set the cookie's expiration property if the user indicated they wanted a persistent cookie.  The code shown in the post is always setting the HttpCookie's expiration date, which has the effect of always making the cookie persistent.

    -Stefan
    ----------------------------------------------------------
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-30-2006, 4:54 PM
    • Loading...
    • MikeOtown
    • Joined on 01-05-2005, 10:12 AM
    • Posts 33

    Thanks.  I'll try that.

     I thought that you could implement your own authentication by implementing the Login control's Authenticate event.  I guess issuing the cookie isn't considered part of authentication.

    I am setting e.Authenticated = true in the Authenticate event.

    So there is no way to tell the Login control to NOT issue a cookie?

  • Re: FormsAuthenticationTicket.Expiration value changing

    10-30-2006, 5:16 PM
    • Loading...
    • sschack
    • Joined on 09-16-2003, 12:06 PM
    • Posts 607
    • AspNetTeam
      Moderator
    Yes - but with the workaround noted earlier:  remove the cookie in the LoggedIn event of the Login control.  I think the control designers felt that with the number of events already on the control, they didn't want to add another one that specifically dealt with issuing the cookie.
    -Stefan
    ----------------------------------------------------------
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-31-2006, 12:35 PM
    • Loading...
    • vivek_iit
    • Joined on 06-18-2006, 6:13 PM
    • New Delhi
    • Posts 3,072
    • TrustedFriends-MVPs

    Stefan,

    I think I am doing something really stupid because your code above doenst seem to be working as expected (and I am not using Login control). Here is my code in the Login page:

    public partial class Login : System.Web.UI.Page

    {

    protected void Page_Load(object sender, EventArgs e)

    {

    string Username = "vivekT";

    if (TextBox1.Text == "a")

    {

    //HttpCookie cookie = FormsAuthentication.GetAuthCookie(Username, true); //true is used to create a persistent cookie

    // cookie.Expires = DateTime.Now.AddMonths(3); //DOESNT WORK in 2.0 as value is taken from "timeout" attribute in the config file

    //Manual cookie issuance

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(Username, true, 200); //hardcoded 200 minute duration

    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

    HttpContext.Current.Response.Cookies.Add(authCookie);

    Response.Redirect("default.aspx");

     

    //Response.Cookies.Add(cookie);

    //Response.Redirect(FormsAuthentication.GetRedirectUrl(Username, true));//redirect to the originally requested page

    }

    }

    }//end class

    Note that if I remove the  commented code, and set the web.config timeout value to a large number, then it seems to work (till the timeout value specified).

    Please let me know what I am missing here!

    Thanks,

    Vivek

    MVP, ASP.NET || My Website || Blog || Articles

    Please mark the most helpful reply/replies as "Answer".
  • Re: FormsAuthenticationTicket.Expiration value changing

    10-31-2006, 3:41 PM
    • Loading...
    • MikeOtown
    • Joined on 01-05-2005, 10:12 AM
    • Posts 33

    You are not setting the Expiration property of the cookie.

  • Re: FormsAuthenticationTicket.Expiration value changing

    10-31-2006, 4:13 PM
    • Loading...
    • sschack
    • Joined on 09-16-2003, 12:06 PM
    • Posts 607
    • AspNetTeam
      Moderator

    I think there is a bit of confusion over the expiration of the forms authentiction ticket, versus the concept of expiration on the cookie itself.  The forms authentication feature only looks at the expiration time set on the forms authentication ticket. It never looks at the expiration date set on the cookie itself.  The reason is that the forms authentication ticket is encrypted and digitally signed, so its payload can be trusted.  However a malicious user can easily forge an Http cookie with a fake expiration date.  The only purpose of the cookie's expiration date in forms authentication is that by explicitly setting an expiry date, the cookie will be persisted in the user's browser cache.  This how "remember me" functionality works - the forms auth ticket is packaged into a cookie and the cookie has an explicit expiration date.  That way when a user returns to the site at some future point in time, the browser just automatically sends the forms auth cookie back to the server.  However the server decrypts the payload of the cookie, and then looks at the expiration date contained in the payload (not the expiry date of the cookie itself) to determine if the forms auth ticket should still be considered valid.

    Unless the intent is to make the cookie stick around on a user's machine, you don't need to set the Expiration property of the HttpCookie.  If you do want a persistent cookie, then when you manually issue it you need to ensure that the expiration date in the forms auth ticket and the expiry on the coookie itself are using the same duration.  Otherwise you can end up in a weird situation where the date in the forms auth ticket and the date on the cookie don't match.

    -Stefan
    ----------------------------------------------------------
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Re: FormsAuthenticationTicket.Expiration value changing

    11-01-2006, 12:19 AM
    • Loading...
    • vivek_iit
    • Joined on 06-18-2006, 6:13 PM
    • New Delhi
    • Posts 3,072
    • TrustedFriends-MVPs

    > If you do want a persistent cookie, then when you manually issue it you need to ensure that the expiration date in the forms auth ticket and the expiry on the coookie itself are using the same duration.

    Thanks for the clarification! But am I right when I say that the behavior has changed in 2.0 because in 1.1 we never used toset FormsAuthenticationTicket explicitly to create persistent cookies. We just used to create a manual cookie, set its expiration time and leave the rest to ASP.NET.

    Also, still there are many ASP.NET 2.0 books out there (some of them quite famous) where it is mentioned that to create persistent cookies, one just needs to create a manual cookie and set its expiration time. No mention of setting FormsAuthenticationTicket's expiration at all!

    Let me know your thoughts on this.

    Vivek

    MVP, ASP.NET || My Website || Blog || Articles

    Please mark the most helpful reply/replies as "Answer".
  • Re: FormsAuthenticationTicket.Expiration value changing

    11-01-2006, 2:17 PM
    • Loading...
    • sschack
    • Joined on 09-16-2003, 12:06 PM
    • Posts 607
    • AspNetTeam
      Moderator

    In ASP.NET 2.0 you also don't need to explicitly create a ticket to create a persistent forms auth cookie.  However what changed between the two releases is that in ASP.NET 2.0 persistent cookies now use the expiration time defined in the forms authentication configuration section.  In ASP.NET 1.0/1.1 persistent forms auth cookies always defaulted to a 50 year expiration.  Because of this difference in behavior developers frequently find they need to manually issue persistent forms auth tickets because they need to use a longer expiration time than what is set in config (by default config is set to 30 minutes I believe).

    Regarding the guidance about setting only the cookie expiration - developers definitely need to make sure the expiration time used when creating a FormsAuthenticationTicket has the correct time in it.  The expiry date on the HttpCookie itself just governs how long the cookie sits in a user's browser cache.  ASP.NET though never trusts that value, and always uses the expiration time from inside of the ticket as the indicator of whether or not the ticket is still considered valid.

    -Stefan
    ----------------------------------------------------------
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Re: FormsAuthenticationTicket.Expiration value changing

    11-01-2006, 2:33 PM
    • Loading...
    • vivek_iit
    • Joined on 06-18-2006, 6:13 PM
    • New Delhi
    • Posts 3,072
    • TrustedFriends-MVPs

    Stefan,

    Thanks a lot for the detailed explaination. Is there any specific reason why this behavior changed? I can only think that using web.config's default value instead of 50 years default will make persistent cookies "more secure".

    Thanks,

    Vivek

    MVP, ASP.NET || My Website || Blog || Articles

    Please mark the most helpful reply/replies as "Answer".
  • Re: FormsAuthenticationTicket.Expiration value changing

    11-12-2007, 1:25 PM
    • Loading...
    • bustell
    • Joined on 07-11-2003, 7:36 AM
    • Rochester, NY
    • Posts 10

     OK, I've just spent 2 hours of my life trying to figure out how FormsAuthentication.RedirectFromLoginPage works and I am more confused than when I started.  I've read all kinds of complicated answers to session time-outs and persistent cookie time-out (which I find interesting... persistent should be persistent).

    I am trying to use the M