Controlling the FormsAuthentication createPersistentCookie expiration - asp.net

In an ASP.NET MVC2 app, we have the standard login action...
if (ValidateUser(model.Email, model.Password)
{
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
...
where the second parameter to SetAuthCookie is createPersistentCookie with the following documentation:
createPersistentCookie
Type: System.Boolean
true to create a persistent cookie
(one that is saved across browser sessions); otherwise, false.
We would like to have the persistent cookie expire after 2 weeks (i.e., a user could return to the site within 2 weeks and not be required to re-authenticate. After that time they would be asked to login again).
How do we set the expiration for the persistent cookie?

Can you not do this?
<system.web>
<authentication mode="Forms">
<forms timeout="20160"/>
</authentication>
</system.web>
The timeout is in minutes.
This timeout value is irrespective of whether or not you are creating a persistent cookie. It simply says that if you don't explicitly terminate the cookie (FormsAuthentication.SignOut), it will automatically expire after the given time period.
In other words, if you do:
FormsAuthentication.SetAuthCookie(someMembershipName, false);
Will result in the cookie expiring when:
The user closes the browser, or
The timeout is reached.
As opposed to if you do:
FormsAuthentication.SetAuthCookie(someMembershipName, true);
Will result in the cookie only expiring when the timeout is reached.
HTH
EDIT:
Take from MSDN:
the timeout attribute is described as follows:
Specifies the time, in integer
minutes, after which the cookie
expires. If the SlidingExpiration
attribute is true, the timeout
attribute is a sliding value, expiring
at the specified number of minutes
after the time that the last request
was received. To prevent compromised
performance, and to avoid multiple
browser warnings for users who have
cookie warnings turned on, the cookie
is updated when more than half of the
specified time has elapsed. This might
cause a loss of precision. The default
is "30" (30 minutes).
Note Under ASP.NET V1.1 persistent
cookies do not time out, regardless of
the setting of the timeout attribute.
However, as of ASP.NET V2.0,
persistent cookies do time out
according to the timeout attribute.
In other words, this expiration setting handles the Forms Authentication cookie only.
The Forms Authentication cookie is a client-side cookie, it has nothing to do with other server-side session you may have (ie a Shopping Cart).
That Session is expired with the following setting:
<sessionstate
mode="inproc"
cookieless="false"
timeout="20"

Related

how to increase session timeout over 1 hour

I want to allow users a longer inactivity timeout setting of over 1 hour. I configured in web.config:
<authentication mode="Forms">
<forms name="MYWEBAPP.ASPXAUTH" loginUrl="~/Welkom.aspx" protection="All"
timeout="181" slidingExpiration="true" path="/"/>
</authentication>
The application pool has the advanced setting:
Idle Time-out (minutes): 181
In the login code I configured the ticket and the cookie:
FormsAuthenticationTicket ticket = new ...
ticket.expiration = DateTime.Now.AddMinutes(180);
...
cookie.Expires = ticket.Expiration.AddMinutes(5);
Response.Cookies.Add(cookie);
The MasterPage prints the ticket.expiration in the footer of each web page, so that I can see what is going on internally.
As is widely known, sliding expiration means that the timeout value is incremented only with a GET request after half of the timeout period has passed. I tested as follows:
At login, I see in the footer an expiration time that is 3 hours ahead.
Every once in a while I do something in the web site, but the expiration time does not change.
If I do something when the expiration is less than 90 minutes ahead, the expiration time is updated to 3 hours from that moment.
However, if I wait longer than 60 minutes, and then do something, while the expiration time is still over an hour ahead, I will get the login page.
Does anybody know how to fix this?
To configure the Session Inactivity Timeout, there are FOUR settings. In my question I mention three settings, and timeout and auto logout in asp.net 2.0 with IIS 7 even after doing all the possible settings mentions the fourth setting: SessionState parameter in Web.config.

ASP.NET MVC - Erasing session data after fer minutes of inactivity

In my web application, i often can see, that when i am not doing anything for a few minutes, and then i come back, and refresh the page - i am still being logged in, but my session data is all gone!
On the login() action i am setting up few Session[] objects that are necessary for a page to work correctly. I have no idea why is it doing so, but i need it to log user out whenever it clears his session data.
I have read about setting <sessionState mode="InProc" timeout="20"/> but will this timeout refresh everytime i refresh the page? Or will it run out after 20 minutes from the time i logged in? What if i make this timer bigger than i have on keeping the user online?
Posting back to the server will keep the session alive for longer. It's a sliding expiration. There are two ways to handle from the client, which the client is not aware of this 20 minute timeout:
Create a timer using client javascript that redirects to the logout page when 20 minutes is hit
Whenever a postback happens, check if the session expired (which can be done in a variety of ways, such as checking Session.IsNewSession, see if your objects are lost, etc.) and then redirect to the logout handler before processing the request.
I assume you are using Forms Authentication. Is that correct? If so, you need to have your Forms Authentication ticket's timeout match the Session timeout.
The user stays logged in through a process that is more complicated than it first seems. A cookie is stored in the user's browser that is called the Forms Authentication Ticket. If the user stays idle past the session timeout limit, the server will discard the session. But on the next request, the Forms Authentication Ticket is passed back to the web server. The server validates the ticket, and if it is still valid, the user is logged back in.
As you can see, the user's session is not restored. If you want that behavior, you would have to detect that condition and restore the session yourself.
The solution is to set the Forms Authentication Ticket's timeout to be the same as the Session timeout. You accomplish that in your Web.config file, as explained here:
<system.web>
<authentication mode="Forms">
<forms timeout="20"/>
</authentication>
</system.web>
The timeout value is in minutes. Once the Forms Authentication Ticket's timeout is hit, the user will be logged out. This operates independent from the session's timeout, but if they are the same, they will expire at roughly the same time. If you want to be completely safe, set the Forms Authentication Ticket timeout to be a little shorter than the session timeout. The user will be logged out before their session times out. When they log in again, they will get a new session. The old session will eventually time out on its own.
Try checking this:
Q: In Proc mode, why do I lose all my session occasionally?
A: Please see the "Robustness" section in the "Understanding session
state modes" section of of this article.
Robustness
InProc - Session state will be lost if the worker process
(aspnet_wp.exe) recycles, or if the appdomain restarts. It's because
session state is stored in the memory space of an appdomain. The
restart can be caused by the modification of certain config files such
as web.config and machine.config, or any change in the \bin directory
(such as new DLL after you've recompiled the application using VS) For
details, see KB324772. In v1, there is also a bug that will cause
worker process to restart. It's fixed in SP2 and in v1.1. See
KB321792.
Source - http://forums.asp.net/t/7504.aspx/1

How to create ASP.NET Membership cookie properly?

I'm using the Membership API for my login system and a wierd thing has been bothering me. I allow user to choose whether to "Remember Me", which means whether to create a persistent cookie with one month expiration period.
In the Web.config, I wrote:
<authentication mode="Forms">
<forms timeout="60" />
</authentication>
This is supposed to be a default session cookie of 60 minutes.
In the code behind of the login page:
if(Membership.ValidateUser(UsernameTextBox.Text, PasswordTextBox.Text))
{
authCookie = FormsAuthentication.GetAuthCookie(UsernameTextBox.Text, RememberMeCheckBox.Checked);
if(RememberMeCheckBox.Checked)
authCookie.Expires = DateTime.Now.AddMonths(1);
Response.Cookies.Add(authCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(UsernameTextBox.Text, RememberMeCheckBox.Checked));
}
The result however is strange. I seem to have created a persistent cookie of 60 minutes! How is this possible?
You are setting the cookie expiration time to be be 1 month, but the authentication ticket that it contains has not been modified. It has inherited the default value of 60 minutes from your web config.
You likely want to synchronize cookie expiration with the authentication ticket expiration, or alternatively set the cookie to have a very long expiry date.
What you need to do is
create a FormsAuthenticationTicket instance manually and set the
Expiration property of the instance.
Use FormsAuthentication.Encrypt() to encrypt the ticket
Add a cookie to the Response.Cookies collection containing the ticket, manually. (rather then using get/setAuthCookie(), which uses
the web.config settings).
Some example code is in the documentation for FormsAuthentication.Encrypt().

Problem: control Session timeout

My session renews every 20 minutes. I've set timeout to 300 minutes but still it renews probably because Application Pool recycles.
I am storing UserId which is Guid in Session which returns null. Problem is when I use Membership using
Membership.GetUser().ProviderUserKey
it works fine. But obviously it makes a database call. How can I prevent this problem from happening? Why does Membership.GetUser().ProviderUserKey succeeds whereas Session doesn't?
In order to complete Jan's and Neil's answers, you should look at your web.config and set both timeouts (sessionState and authentication)
<sessionState timeout="300"/>
Sessionstate timeout specifies the number of minutes a session can be idle before it is abandoned. The default is 20.
<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="300" />
</authentication>
Forms timeout is used to specify a limited lifetime for the forms authentication session. The default value is 30 minutes. If a persistent forms authentication cookie is issued, the timeout attribute is also used to set the lifetime of the persistent cookie.
Your session may still be alive (if you set it to 300 minutes) but the ASP.NET membership could be expiring?
Have you increased the authentication timeout too?
<authentication mode="Forms">
<forms loginUrl="Login/" timeout="180"/>
</authentication>
You are mixing authentication and session. These are two completely different concepts.
GetUser() return the currently authenticated user form your MemberShipProvider.
Session and authentication have different timeouts - so its valid that your session times out but the user is still authenticated.

what's differences between "forms timeout", "membership userIsOnlineTimeWindow" and "sessionState timeout"

What is the difference between these lines of code:
<forms timeout="5" />
<membership userIsOnlineTimeWindow="5" />
<sessionState timeout="5" />
Thanks a lot.
Forms (FormsAuthention) are used for authentication and when it times out it will logout user. You can 'prevent' timeout by setting SlidingExpiration property to 'true' and it will renew forms ticket on user activity (read request to asp) if needed. This will keep user logged on while he is 'active' on your site.
Membership is used for user validation and userIsOnlineTimeWindow is there to help you track user activity so when it runs out it will set IsOnline property to 'false' for that user. One new thing I found out is that it will also renew forms ticket while users isOnline is set, main difference is that it doesn't renew itself automatically but only when its GetUser() or ValidateUser() methods are run.
When session times out you will lose data found in Session object. That is all.
Note the following behavior:
You set Session timeout = 10 minutes and Forms Authentication timeout = 8 minutes.
The user logs into your site using Forms Authentication.
Both the Session "clock" and Forms Authentication "clock" start running.
Suppose that you keep some info needed for the site's operation in the Session(For example, Session["userData"] = userData;).
The user is idle for 9 minutes.
At 8 minutes the session times out and the user's data is cleared.
At 9 minutes when the user tries to perform some activity on the site, you naively reference the Session["userData"] to get his info. Since it is null he will get error 500 for a null reference.
Conclusion: Keep the forms authentication timeout shorter than the session timeout.

Resources