How can i close the session after x time - c#

In ASP.NET on IIS 7.5, how can I close the session after an amount of time (lets say 5 hours), even if the user is still working and there is no idle time?
Is there a property in IIS or should I do it in code?

Have you tried the web.config?
<configuration>
<system.web>
<sessionState
mode="InProc"
cookieless="true"
timeout="30" />
</system.web>
</configuration>
I'm also assuming you have a basic site with no load balancing or session state servers. Those require different approaches.

I haven't tried such a solution before but here's what come into mind :
In your global.asax handle SessionStart and when a new session is started create a new (Asynchronous )Task that starts a timer (a timer that execute once after 5 hours and calls Session.Abandon() :
Something like this :
new Task(()=>{
var timer=new Timer{Interval=DateTime.Now.AddHours(5), Elpased+=(obj,args)=>{
session.Abandon();
((Timer)obj).Stop();
((Timer)obj).Dispose();
}
}).Start()
As I told you I haven't test it and since everything is working asynchronously here it might led to unknown situations.
(BTW as far as I know timer will already run in another thread so no Task is needed :) )
Update
OK, It seems that we can't hold a reference to a HtmlStateSession. Thus here's another approach that I think it can help: In this approach we hold a registery of session id and start time of each session in a static dictionary and when a request begins we check if its session (according to its session id) has been out there more than 5 hours and if that is the case we Abonden the session.(and remove the id from dictionary of course)
There's no need to have thousands of timers this way and we don't expire the sessions right away but we wait until the next time that user sends us a request.

What about setting up windows task scheduler to run an aspx page that will check how long the user is logged in and according to it, to decide if to close the session or not.
(You can save in your database, a log-in time for each user).

Related

BotDetect Captcha Issue: New Session Initialized on Postback

Good Day!
I just need some help regarding this issue that I'm encountering using BotDetect Captcha.
Issue: Session Troubleshooting: New Session Initialized on Postback, potential timeout or Session resume problem
I'm using version 4.1.0.0 of BotDetect.dll in asp.net/SharePoint site.
The issue is happening upon clicking the Submit button in the page and when it postback to validate the page inputs, the captcha section will fail and show this issue.
This is the code that I use to validate the captcha input:
isValid = BotDetectCaptcha.Validate(CaptchaCodeTextBox.Text.Trim().ToUpper());
if (isValid){ //code here }
The thing that makes me wonder is that this code is working fine in my Dev environment which I'm using default values in the web.config of the site.
However, when we deployed this to the staging server, this error occurs.
One thing to point is the sessionState in dev is just inProc and in staging, it is using a custom sessionState to an SQL DataBase - and I'm not sure if this is the cause.
Here is the sessionState setting in staging:
<sessionState mode="SQLServer" timeout="60" allowCustomSqlDatabase="true" sqlConnectionString="Data Source=<server>;Initial Catalog=<table>;Integrated Security=True;Enlist=False;Pooling=True;Min Pool Size=0;Max Pool Size=100;Connect Timeout=15" />
I have no control of the settings of the iis/site in the server so this is getting harder on my end so I'm hoping someone might be able to point directions on what to check or troubleshoot.
Thank you very much!
It turns out to be a server issue after all. Something with regards to network blocking connections to some resources.Tried to deploy the same to other server and it is working.

NewRelic, async http handler and AcquireRequestState

I have a problem with one async handler in distributed ASP.NET web app. First let me explain a use case:
application uses IIS 8 on win 2012 machine with .NET Framework 4.5.2
application has disabled Session and authentication modules via web.config like this
<system.webServer>
....
<modules>
<remove name="WindowsAuthentication" />
<remove name="Session" />
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
application uses custom async web handler to serve the specific request
application has very heavy traffic (about 50k requests per minute per server, async handler has about 10k requests per minute per server all tracked from NewRelic)
application is distributed via multiple w3wp processes (2 w3wp processes) and multiple virtual servers (about 10 servers)
application has high amount of connections
All normal (sync requests) are working fine but async request that does a little more work (that's why we use async request) is often slow but NewRelic reports that it is slow because of "AcquireRequestState". Now I've looked on google and stack overflow and this event is connected to creating a Session but we have sessions disabled in web.config. Does anyone know what else could "AcquireRequestState" could be doing? Are we missing some place to remove session state? Adding that from web.config to machine.config did nothing...
Here is a snippet from a request in NewRelic:
**Slowest components Count Duration % **
AcquireRequestState 1 12,600 ms 100% --> WTF?
ExecuteRequestHandler 1 5.01 ms 0%
Integrated Pipeline 1 0.334 ms 0%
UpdateRequestCache 1 0.3 ms 0%
EndRequest 1 0.168 ms 0%
AuthenticateRequest 1 0.161 ms 0%
Total time 12,600 ms 100%
EDIT:
I have <sessionState mode="Off" /> in web.config (<system.web> section) so that is not it.
I've looked into this because we had similar issues, I found this forum post, the reply that is interesting is this:
Unfortunately, the issue is not as simple as just turning sessionState off. In fact, one of the key phrases when describing the challenges with AcquireRequestState is the phrase for example, session state when it comes to when this event is raised. In digging deeper into this (actually looking at the .NET source) we can see that this is called when an EventHandler is executed or a RequestNotification object is created. I daresay there are other methods and/or events that, when called, will raise an AcquireRequestState event. Tracking down all of them represents something of a struggle. It seems this is something not talked about a lot outside of the more normalized session state discussions.
The most common place we see this event raised is certainly related to session state management. But there are very obviously outliers where these event can still be raised. It can even be called directly from application code. The thing the agent grapples with is that it can identify the event, but rarely the source. When it is raised as part of the ASP pipeline, the only notification the agent gets is that this is one segment of the transaction. The source, or the methods executed inside of the event, is something the agent is rarely instrumenting by default.
I wish we could offer more insight for you on this. There are a lot of moving parts inside of a .NET application, some of which involve the operating system itself, IIS, the version of .NET, whether or not the methods are asynchronous, application pool settings, execution modes, permissions, etc.
While I don't want to open a second can of worms here, this harkens to the issue with the lack of stack traces for 500 errors. The agent provides a stack trace when it is offered and/or available. Where the stack trace, if one even exists, occurs within the ASP pipeline is extremely important. Sometimes it occurs before any actual application code is executed. In such cases the error is reported to the application, which in turn lets the .NET agent see and report that an error occurred, but no other details are provided. The agent simply sees that it happened and reports as much information as is possible. Beyond that the agent simply has no further details it can offer.
We gave up, so I'd be interested to know if you figure it out!
AcquireRequestState is also used by the Profile Module. Did you try disabling that?
<modules>
<remove others unwanted modules... />
<remove name="Profile" />
</modules>
So I had this same issue. I had a lot of concurrent ajax requests that all used variables stored in ASP.NET ClaimsIdentity, which is effectlively using the SessionState. This meant, that a lot of the server response time was just waiting for the SessionState to be unlocked.
I solved it by decreasing the Lock Polling interval:
var sessionStateModuleType = typeof(SessionStateModule);
var pollingIntervalFieldInfo = sessionStateModuleType.GetField("LOCKED_ITEM_POLLING_INTERVAL", BindingFlags.NonPublic | BindingFlags.Static);
pollingIntervalFieldInfo.SetValue(null, 30); // default 500ms
var pollingDeltaFieldInfo = sessionStateModuleType.GetField("LOCKED_ITEM_POLLING_DELTA", BindingFlags.NonPublic | BindingFlags.Static);
pollingDeltaFieldInfo.SetValue(null, TimeSpan.FromMilliseconds(15.0)); // default 250ms
The solution above was disclosed in this blog article

Does SessionID change for each call to webservice?

I don't understand the notion of session for webservices. In one hand you can allow session in DataAnnotation like that :
[WebMethod(EnableSession = true)]
In the other and you can configure the session state in IIS :
So I put Session State in process and set the delay for 20 minutes.
Then in my webservice I try to get the session ID like that :
return HttpContext.Current.Session.SessionID
I use a winform to get this information and call the webservice.
And the session ID Change at every call. I don't understand why, beaucoup SessionState is set to 20 minutes...
May I'm in wrong way ? Can you explain me ?
Is SessionID correspond to the Session State in IIS ?
There must be something that connects the request to a particular session. Usually a cookie is used for that. This cookie is sent along with the response, so the calling application must remember that cookie and send it along with the next request. Without cookie the request is handled as if it's a new session.
A browser handles this by default (unless specifically switched off), for an other application you need to do cookie management yourself. For this you need to use a single CookieContainer that will be shared among your requests.
See the link in the answer by Marius for more details.
I was thinking of a solution, but then I found this post :
How to keep session alive between two calls to a web service in a c# application?
I hope this helps.
If you want to keep your sessionID same througout users session life time you should add a global.asax file to your web project and implement Session_Start method.
Please check this link:
https://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

Session ends randomly after redirect

I have a strange problem in ASP .NET MVC 4. In AccountController I am doing redirects on certain actions and put data into TempData (which is stored in Session) before that:
[AllowAnonymous]
public ActionResult Activate(string token)
{
new CustomSignupService().Activate(token);
TempData["Message"] = "User was successfully confirmed";
return RedirectToAction("Message", "Home")
}
Now I know I could just return shared Message view in this case, but this is just a code sample to reproduce the problem.
CustomSignupService.Activate does a db lookup via NHibernate and updates user in transaction (user activation). Sometimes (lets say 1/5 tries in 5 minutes) TempData does not make it throught the redirect, so I added logging into Session_End and noticed that session ends when RedirectToAction is invoked. Right after that Session_Start is invoked but of course TempData is gone.
Session has default timeout (20min) and controllers use SessionStateBehavior.ReadOnly
Any ideas?
UPDATE
Step 1: It's not Application Pool recycling (I turned on all General Recycle Event Log entries on Application pool and checked event log, after session restarts but recycle is not causing it)
I had a problem with Session being lost. I used Fiddler and noticed that there was a duplicate ASP.NET session cookie with a blank value. I don't know how it got there. So a new session was created on every request. I deleted that duplicate cookie and the problem was solved.
Other unlikely reasons are:
IIS process recycle
Session.abandon being called
modifying bin folder or web.config causing app restart
Check out this page:
Losing Session State
I don't know ASP.NET MVC but in the dark centuries I used ASP.NET without MVC. I struggled several times with unexpected session ends. Most of the time it was caused by some simple things which are described in the article http://www.c-sharpcorner.com/uploadfile/technoNet/session-timeouts-causes-and-remedies/
Sometimes the server has entries in the event log that gives you a little bit more information.
And some other solutions might be
ASP.NET Session ending abruptly
random IIS session timeout

ASP.NET SessionState TimeOut not working

I want my web page to close when SessionState timeout occures. This is my code in my web config:
<system.web>
<sessionState timeout="1" mode="InProc"/>
</system.web>
I set to 1 minute for testing purposes. The following is my Global.asax code:
protected void Session_End(object sender, EventArgs e)
{
Response.Redirect("~/LogOut.aspx");
}
I put a label on one of the pages in order to check the session timeout, this is the code in the Page_Load event:
lblSession.Text = "SESSION TIME: " + Session.Timeout.ToString();
When I enter the site and come to this page the label shows SESSION TIME: 1, but after 1 minute I don't get redirected to the LogOut page and the present page is still fully active and working, apparently meaning that the session has not been terminated.
I am working in Visual Studio 2008 thru the development server so suggestions I've seen relating to IIS settings don't seem to be relevant at this stage.
Please help!
HTTP is a request / response protocol. There is no persistent connection between the browser and the server. The code in Session_End thus effectively does nothing — it can't tell the browser to do anything.
You would need to make a (client-side) JavaScript timer and actively load the logout page right before the session timeout elapses.
Session_End in my experience gets called on the first postback (could be implemented via a client-side Timer) after the timeout occurred - whenever that might be... if the user just closes the browser this event may never be called (except for the case you made a specific JS handler unload to do the postback in that situation).
For some information see:
http://justgeeks.blogspot.com/2008/07/aspnet-session-timeouts.html
http://www.highoncoding.com/ArticleDetails.aspx?articleID=108
http://forums.asp.net/t/1271309.aspx/2/10
http://www.codeproject.com/KB/aspnet/PageTracking.aspx
http://p2p.wrox.com/asp-pro-code-clinic/1648-session_onend-not-firing.html
http://aspalliance.com/1182_Troubleshooting_Session_Related_Issues_in_ASPNET.all
This doesn't seem to be the correct way of testing your session timeout. Try putting something in the session variables. Don't touch the page for another couple of minutes, and try reading it back from Session. If your session is alive, you should be able to see the variables, else... you won't.
Learn more about session and troubleshooting session... http://aspalliance.com/1182_Troubleshooting_Session_Related_Issues_in_ASPNET

Categories