> 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!
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.
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".
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 Microsoft Login control, but have custom code behind the authenticate event.
The code basically says if the user's password is good (look up in dateabase), then perform
FormsAuthentication.RedirectFromLoginPage(Me.Login1.UserName, Me.Login1.RememberMeSet)
Unfortunately, if the user click Remember Me, it does really remember them. Very frustrating. I have searched the Internet and can't come up with an answer / explanation that I understand. Maybe, I'm just being stupid today. I'm not sure.
In one forum, it was mentioned that you can not use RedirectFromLoginPage within the authenticate event because it was too early to set the cookie and that had to be done in the LoggedIn event. So I added e.authenticated = True to my authenticate event
and then added the FormsAuthentication.RedirectFromLoginPage(Me.Login1.UserName, Me.Login1.RememberMeSet) to the LoggedIn event. Still not working.
Does anyone have an example of how to use the login control with your own custom authenticate event? I'm not using Microsoft's Membership at all. I have my own user/roles/resources tables that I authenticate with.
The behavior you are seeing is because when you access cookies from the Request object, the expiration date of the cookie is not available. The client-side browsers retain the expiration date for each cookie stored in the browser cache - but that information
is never sent over the wire when cookies are subsequently sent back to a server.
You can see that behavior by using a protocol trace tool like Fiddler and seeing what information is sent from the server to the browser the first time a cookie is issued. Then compare that to the cookie being sent from the browser to the server on subsequent
calls.
I think the reflection code is from the part of OnAuthenticate that only runs if forms authentication detects the need to refresh the forms authentication ticket. Since refreshing the ticket occurs at roughly the 50% point of the ticket's time-to-live,
the associated code in OnAuthenticate normally won't run and hence the HttpCookie instance from the Request object won't be touched.
-Stefan
----------------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
The results came the same, the first time the application creates an authentication cookie, the cookie value, path, HttpOnly, and expirtation date are sent back to the client, while the next request has only the encrypted pay load or FormsAuthenticationTicket.
What caught my attention is that inside the OnAuthenticate event, there is this code:
This shows that the FormsAuthenticationModule never looks at the expiration date of the cookie, it only makes sure there is an authentication cookie. So I guess, if the cookie is available, it will simply grab the FormsAuthenticationTicket, do the checkings
on the ticket itself if valid or not, regardless of the request cookie.
Finally, just wondering about this statement: "Since refreshing the ticket occurs at roughly the 50% point of the ticket's time-to-live"
Forms authentication only looks at the contents of the ticket because a malicious user client has control over all of the data sent in an HTTP request. However the forms authentication ticket itself is encrypted by ASP.NET and thus ASP.NET can trust its
contents.
If you set the timeout for a forms authentication ticket to 20 minutes, and you enable sliding expirations, then when a request arrives and ASP.NET determines that 10 minutes of life-time (or less) remains for the authentication ticket, ASP.NET will generate
a new one with an updated expiration date.
-Stefan
----------------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
vivek_iit
All-Star
17776 Points
3186 Posts
MVP
Re: FormsAuthenticationTicket.Expiration value changing
Nov 01, 2006 04:19 AM|LINK
> 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
Communifire: Social Networking and Business Collaboration Platform
sschack
Contributor
3085 Points
617 Posts
AspNetTeam
Moderator
Re: FormsAuthenticationTicket.Expiration value changing
Nov 01, 2006 06:17 PM|LINK
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.
----------------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
vivek_iit
All-Star
17776 Points
3186 Posts
MVP
Re: FormsAuthenticationTicket.Expiration value changing
Nov 01, 2006 06:33 PM|LINK
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
Communifire: Social Networking and Business Collaboration Platform
bustell
Member
24 Points
27 Posts
Re: FormsAuthenticationTicket.Expiration value changing
Nov 12, 2007 05:25 PM|LINK
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 Microsoft Login control, but have custom code behind the authenticate event.
The code basically says if the user's password is good (look up in dateabase), then perform FormsAuthentication.RedirectFromLoginPage(Me.Login1.UserName, Me.Login1.RememberMeSet)
Unfortunately, if the user click Remember Me, it does really remember them. Very frustrating. I have searched the Internet and can't come up with an answer / explanation that I understand. Maybe, I'm just being stupid today. I'm not sure.
In one forum, it was mentioned that you can not use RedirectFromLoginPage within the authenticate event because it was too early to set the cookie and that had to be done in the LoggedIn event. So I added e.authenticated = True to my authenticate event and then added the FormsAuthentication.RedirectFromLoginPage(Me.Login1.UserName, Me.Login1.RememberMeSet) to the LoggedIn event. Still not working.
Does anyone have an example of how to use the login control with your own custom authenticate event? I'm not using Microsoft's Membership at all. I have my own user/roles/resources tables that I authenticate with.
haidar_bilal
All-Star
45607 Points
8728 Posts
MVP
Re: FormsAuthenticationTicket.Expiration value changing
Apr 05, 2008 11:35 AM|LINK
Hi Stefan,
I am noticing a strange behavior in ASP.NET 3.5.
I have added the following into the page_load of the Login.aspx page:
FormsAuthentication.RedirectFromLoginPage("testuser", true);
Inside the page_load of the Default.aspx page, I add the following:
// Retrieve the FormsAuthentication Cookie HttpCookie cookie = (HttpCookie)Request.Cookies[FormsAuthentication.FormsCookieName]; // Get the cookie's payload == Enrypted FormsAuthenticationTicket string encryptedTicket = cookie.Value; // Decrypt the cookie's payload FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket); Response.Write("Ticket Expiry Date: " + ticket.Expiration.ToLocalTime().ToLongDateString() + ticket.Expiration.ToLocalTime().ToLongTimeString() +" <br/>"); Response.Write("Cookie Expiry Date: " + cookie.Expires.ToLocalTime().ToLongDateString() + " " + cookie.Expires.ToLocalTime().ToLongTimeString() + " <br/>");The output generated is:
Ticket Expiry Date: Saturday, April 05, 20083:00:44 PM
Cookie Expiry Date: Monday, January 01, 0001 2:00:00 AM
If however, you check Reflector, you will notice the following code located inside the private OnAuthenticate method:
if (ticket.IsPersistent) { cookie.Expires = ticket.Expiration; }What can be said now?
Thanks
sschack
Contributor
3085 Points
617 Posts
AspNetTeam
Moderator
Re: FormsAuthenticationTicket.Expiration value changing
Apr 07, 2008 08:02 PM|LINK
The behavior you are seeing is because when you access cookies from the Request object, the expiration date of the cookie is not available. The client-side browsers retain the expiration date for each cookie stored in the browser cache - but that information is never sent over the wire when cookies are subsequently sent back to a server.
You can see that behavior by using a protocol trace tool like Fiddler and seeing what information is sent from the server to the browser the first time a cookie is issued. Then compare that to the cookie being sent from the browser to the server on subsequent calls.
I think the reflection code is from the part of OnAuthenticate that only runs if forms authentication detects the need to refresh the forms authentication ticket. Since refreshing the ticket occurs at roughly the 50% point of the ticket's time-to-live, the associated code in OnAuthenticate normally won't run and hence the HttpCookie instance from the Request object won't be touched.
----------------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
haidar_bilal
All-Star
45607 Points
8728 Posts
MVP
Re: FormsAuthenticationTicket.Expiration value changing
Apr 07, 2008 08:56 PM|LINK
Hello Stefan,
The results came the same, the first time the application creates an authentication cookie, the cookie value, path, HttpOnly, and expirtation date are sent back to the client, while the next request has only the encrypted pay load or FormsAuthenticationTicket.
What caught my attention is that inside the OnAuthenticate event, there is this code:
FormsAuthenticationTicket tOld = null;
bool cookielessTicket = false;
try
{
tOld = ExtractTicketFromCookie(e.Context, FormsAuthentication.FormsCookieName, out cookielessTicket);
}
catch
{
tOld = null;
}
And inside the ExtractTicketFromCookie,
HttpCookie cookie = context.Request.Cookies[name];
if (cookie != null)
{
encryptedTicket = cookie.Value;
}
This shows that the FormsAuthenticationModule never looks at the expiration date of the cookie, it only makes sure there is an authentication cookie. So I guess, if the cookie is available, it will simply grab the FormsAuthenticationTicket, do the checkings on the ticket itself if valid or not, regardless of the request cookie.
Finally, just wondering about this statement: "Since refreshing the ticket occurs at roughly the 50% point of the ticket's time-to-live"
Thanks a lot!
Regards
sschack
Contributor
3085 Points
617 Posts
AspNetTeam
Moderator
Re: FormsAuthenticationTicket.Expiration value changing
Apr 07, 2008 09:53 PM|LINK
Forms authentication only looks at the contents of the ticket because a malicious user client has control over all of the data sent in an HTTP request. However the forms authentication ticket itself is encrypted by ASP.NET and thus ASP.NET can trust its contents.
If you set the timeout for a forms authentication ticket to 20 minutes, and you enable sliding expirations, then when a request arrives and ASP.NET determines that 10 minutes of life-time (or less) remains for the authentication ticket, ASP.NET will generate a new one with an updated expiration date.
----------------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.