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

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

Related

Session timeout is not working while using SqlServer mode

I am developing ASP.Net MVC application.
We have used sessionState mode SQLServer and i have set timeout to 20 minutes.
<sessionState mode="SQLServer"
sqlConnectionString="data source=127.0.0.1;user id=sa;password=sa"
cookieless="false"
timeout="2" />
Code is something like this in web config.
I have also set login page.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Now when session expires i want to navigate user to login page.
I checked many things but i was unable to understand how it exactly works? and how can i navigate user login page on session expire?
It is working in InProc mode. I used it in same way and user is redirected to login on session expire.
But i am unable to accomplish same thing in SQLServer Mode.
I am unable to understand what i am missing?
I checked Session State and also found that Session timeout handled in SQLServer Mode
Edit :-
I want to redirect user to login page whenever another http request is executed for that session.
Ordinarily the browser has no idea what is going on on the server. Unless an HTTP round trip occurs, it will remember the state of the session from when the page was rendered.
In addition, you session cookie is probably HttpOnly, so there is no way for the page to check for the presence of a session cookie.
One way to accomplish what you want is:
Add a hidden iFrame to your page. Set the SRC of the iFrame to a handler in your web site
The handler doesn't have to do much except return a 200 OK, plus a refresh header set to a few seconds, so that the handler gets continually polled.
context.Response.AddHeader("REFRESH", "2");
Add framebreaker code to your login page
if (top.location != location) {
top.location.href = document.location.href ;
}
When a request for the handler occurs with an expired session, it'll get redirected to the login page via forms authentication; when the login page is returned, it'll break your iFrame and redirect the full window to the login page.
Or, you can do what everyone else does, which is wait for the user to request another page.
For me, changing the timeout value in the web.config file to anything didn't take place, and the reason was there were somehow some leftover old records in the ASPStateTempSessions table in ASPState database. I had to empty the table and only then my web.config changes took place. I wasted an hour trying to search for the cause so hope this helps someone.
So, run this:
delete from ASPStateTempSessions
Difference between InProc and SQLServer mode is that SQLServer relies on MSSQL job to remove the session. It actively doesn't prevent you from login again.
See Session State Providers
SqlSessionStateStore doesn't actively monitor the Expires field. Instead, it relies on an external agent to scavenge the database and delete expired sessions—sessions whose Expires field holds a date and time less than the current date and time. The ASPState database includes a SQL Server Agent job that periodically (by default, every 60 seconds) calls the stored procedure DeleteExpiredSessions to remove expired sessions.

How to troubleshoot MVC/Identity 2 authentication timeout

User authenticates, but is becoming unauthenticated within a minute or minutes. Seems to happen at random, but is within a handful of minutes.
Is there a breakpoint I can set someplace where logout is occurring , or a method of troubleshooting why a user is being logged out?
This doesn't seem to happen on localhost when running the project using VS, but is happening on the remote host after publishing.
Set the session state in IIS or the web.config:
<system.web>
<sessionState timeout="60"/>
...
That sets the timeout to be 60 minutes. You should also lookup session state modes.

ASP.Net MVC: Session duration?

Due to the complex business logic, I had to implement myself the authentication. I'm storing the authentication with:
FormsAuthentication.SetAuthCookie(identifier,false);
The False is to indicate that we don't want to have persistent cookie
I've to also store in session some informations(one information that the user has to enter to login, indicating for which set of data he wants to access).
I'm storing those data through model binder.
It's working fine most of the time. But sometime after an inactivity period, we are still logged but we don't have any data in session.
I would like that the duration of my session is the same than the login session, to avoid this kind of "I'm logged but I've lost some data in the session".
I don't need/want to have a persistent connection.
How should I proceed to have this system?
I believe the FormsAuthentication uses its own timeout. You can configure your web.config accordingly:
<system.web>
<authentication mode="Forms">
<forms timeout="50"/>
</authentication>
<sessionState timeout="50" />
</system.web>
In fact, There was a Session timeout by default in the IIS Application pool, so, to avoid this problem:
Go on IIS Manager
Go on the ServerName/Application Pools tab
Right click on the concerned application pool
Click on Advanced Settings,
In the section "Process Model", put an higher value in the "Idle Time-out"(this is in minutes
Click on OK
Restart the application pool
For me, this + the Yannis config(setting the same value for the form timeout+session state timeout) worked.

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.

Why might my users be being logged out after a minute or so?

I have a Asp Mvc 2 site using forms authentication. When I run it locally I can log in and stay logged in indefinitely.
However when I put it on the server I seem to only stay logged in for a few minutes and then seems to be logged out. I have looked at the cookies and there are 2 which seem relevant:
.ASPXAUTH which is a session cookie
.ASPXANONYMOUS which expires in 3 months.
When I refresh the page the cookies stay the same until I get logged out, when I seem to get a new .ASPXANONYMOUS cookie, but the .ASPXAUTH seems to be the same.
It seems that I might be able to stay logged in until I do something after a certain amount of time. If I submit a form as soon as I am logged in then it works ok, but if I keep submitting data again and again then after a minute or so, one of the submits will happen as a logged out user and not as the user who was logged in, which all the other submits worked as.
What might cause this behaviour and how can I track down what is different & change it so that I can stay logged in indefinitely?
EDIT,
its a single server, but after some more investigation and searching the likely candidate seems to be that I am using more than 100mb on the server and the application pool is getting recycled. I suppose now i need to know
How can I check how much memory I'm using.
What advice there is to reduce that.
Could it be that the ASP.NET application is being re-cycled or shutdown (e.g. due to idle timeout, or newly built/changed assemblies)?
When an ASP.NET web application starts up it will, by default, generate encryption keys for view state and session cookies. This will invalidate any such data originally served from an earlier run of the application (or from a different system).
To have sessions survive ASP.NET application cycles (and multi-server farms) you can specify the keys in your web.config:
<system.web>
...
<machineKey
decryption="AES"
validation="SHA1"
decryptionKey="..."
validationKey="..."
/>
where decryptionKey and validationKey are hex strings of length depending on the algorithm (with AES: 64 digits and SHA1: 128, for other algorithms check MSDN).
These keys should be cryptographically generated, and .NET has the types to do this which can be used from PowerShell:
$rng = New-Object "System.Security.Cryptography.RNGCryptoServiceProvider"
$bytes = [Array]::CreateInstance([byte], 16)
$rng.GetBytes($bytes)
$bytes | ForEach-Object -begin { $s = "" } -process { $s = $s + ("{0:X2}" -f $_) } -end { $s}
For AES use the above array length, for SHA1 use a length of 64.
It is quite likely that Session Timeout on the web server is configured to a much smaller timespan than you have set in your Form Authentication configuration in web.config.
The default Session Timeout is 20 minutes for IIS6 and IIS7.
If you have access to the web server's admin interface, you can raise the timeout via the GUI, but it can also be set from the config file if your IIS7 using the <sessionState> and <sessionPageState> sections:
http://msdn.microsoft.com/en-us/library/cc725820(v=ws.10).aspx
Check the webconfig authentication section
<authentication mode="Forms">
<forms name="UniqueName" loginUrl="login.aspx" path="/" >
</forms>
</authentication>
Ensure that the authentication cookie name for each hosted site is unique.
Came here with a similar issue, following the suggestion by #Richard, I looked at the Application Pools' recycling settings. What I found was the settings were changed and the Regular time intervals (in minutes) value was set to 1 minute. This meant that the app pool was being recycled each minute.
To change that, Right-click on the application pool, select the Recycling option, change the value under Regular time intervals (in minutes). I set it to the same value as the other Application Pools were using.
This change fixed the issue, turns out it was set to a low value a while back while during some misguided troubleshooting with an expired SSL certificate.
If none of these work, check in the Application Pools and ensure that the Idle Timeout is set to 20+ minutes. Click on the application pool, select the Advanced Settings link to the right, find the Process Model section, and increase the Idle Timeout value there.

Resources