Weird problem here, we're running a few mixed environment web applications, that use Windows or Forms authentication depending on where the user comes from.
I'm curious how everyone else might be handling expired sessions to avoid the errors you would get from someone leaving an idle session open for too long and then trying to resume work, mainly looking for best practices on the subject.
Any suggestions or opinions would be greatly appreciated.
Thanks,
I'm not sure how your authentication method affects session timeouts, the mechanism they use to get in shouldn't affect how long they can stay in.
Generally speaking, if someone does have an expired session, you can add code to check to see if their session is active. If it isn't, just redirect them to a login page, or display some other friendly text.
Basically something like:
if (Session.IsNewSession)
Response.Redirect("login.aspx");
Don't store unnecessary information on the session.
If you are storing something you can reload, have the appropriate code that will reload it if it wasn't found in the session
Consider if some processes are meant to be handled in long periods of time, in which case save intermediate info to the database.
If the user is doing a process that uses the session, and the data is missing, take them to step 1 (not much you can do about it, if you don't have the info elsewhere).
Related
Problem description
I have an ASP.NET app in which the users have different rights, and are logged in through Facebook. The app includes (among other things) filling out some forms. Some users have access to forms others don't. The forms can sometimes require some searching in books and/or on the internet before being able to submit them.
As such, we're having problems with session time-outs (it seemed), where users would be met with "Not authorized to see this page/form" after doing research somewhere else.
Attempted solutions
I've created a log function that logs the state of a handful of variables on strategic points in the application. I've pinpointed the problem to the fact that the Session variable "UserRole" is null when the problem occurs.
Relogging
The obvious solution is: "Have you tried relogging?" - which should reset the session and allow the user back to the form they want. On logout, I use
Session.Clear();
Session.RemoveAll();
and I create a new session with relevant variables (including UserRole) on login. This doesn't help, though.
Keeping session alive
One way to do it is just increase the standard 20-minute Session length to an arbitrary, higher number (say 2 hours). Although that could be viable during beta (there are only around 5 users right now), it is not a viable solution in the long haul as the server would have to keep the Session objects from many users for longer time, exponentially increasing server demands.
Instead, I created a 'dummy' .ashx handler "RefreshSession.ashx", that can recieve a POST request and return "200" statuscode. I then created a jQuery function in the shared part of the app (that all the pages use) that calls this handler every 10 minutes in order to refresh the session as long as the tab is open in the browser. I've checked the network traffic, and it works as intended, calling the handler even if the window is minimized or the user is viewing another tab. This did not solve the problem either.
A caveat
When one of the users encounter the problem, they call me or my programming partner up. Of course, we go and see if we get the same issue. We all have the same (admin) rights. The 'funny' thing is that we see the exact same error on the same subpage - even if we haven't had any contact with the application for days.
The problem will 'fix itself' (i.e. let users with proper role back on the subpage) after a while, but not even republishing the app to the server will reset it manually.
Therefore, it seems to not be a simpel session error as supposed from the "UserRole" session variable being null after 15-20 minutes of inactivity. It seems to be saved somewhere internally in the server state.
My problem is, that I now have no idea where to look and how to progress. I was hoping that someone here might have an idea for a solution, or at least be able to point me in the right direction? :-)
Thank you all for your time, it is much appreciated.
Based on MaCron's comment to the question, we decided to keep the information in the user's cookies instead of the session variables. Everything seemed to point to us having exactly that issue, and deadlines being deadlines and with me not being able to figure out how to disable the synchronization of worker processes, this seemed to be a feasible and comparatively easy fix.
we have a vb.net application with send and receive mailing also. Now we have added a session timer of 30 min but the users are complaining that they are facing a problem when they write a long text message or while composing they get busy in something else and when they return back to continue composing message , they are redirected to a session expiry page, and their long text message is gone forever. So I am new to this and I was thinking like , when the user is in compose message the text should be automatically saved to drafts like hotmail.
Any help will be appreciated . Thank you.
There are two basic approaches you can take to this:
The proper "web" way would be to remove the need for session and state from at least this part of the application i.e. set up the application so that its resilient if the session expires and can pick up the necessary user details etc from the post if the session has expired - you can do this with a value stored in viewstate or in a cookie. However this doesn't deal with the problem of saving work in progress.
So the more appropriate solution here will be to investigate AJAX solutions to the problem whereby the page uses client side scripting to transparently "save" (post) the message text back to the server at defined intervals. This has the further advantage of prolonging the session as well.
Of course with the AJAX solution your back end data management becomes more complex too... but it that's manageable (limit it to one draft in progress and remember to clear out the draft on "send" and you should be fine) and you may still want to consider some degree of additional resiliency for loss of session for other reasons.
I am searching to find a way to read and write on session data but with out having the HttpContext. Current.
Why I won to do that ? because I wish to make some action with the user Session after the page have been close and unloaded.
For example, a user load and see a page, then I create a thread to make some action and let user go. Inside this thread I like to read the session data, but in this case HttpContext . Current is not exist any more.
So is there a way to read Session Data knowing just the session id.
I store my session inside an SQL server, and I see them. its there on table ASPStateTempSessions :)
How can I read them "offline" and manipulate them ?
Thank you in advanced.,
Still not quite clear why you might want to do that but you might not actually need to do it on Session_End(). At that point, it may be too late for you to work with the session data anyway (I've read some articles before about this). What might be a better solution is to actually attempt to work on the session data when your application actually has the context.
For example:
There's nothing to stop your application creating an asynchronous request on a new thread in the background (or even a different application, such as a Windows Service, for instance) when the specific session variable that you want is updated or has been set. This way, your application will be able to access the current HttpContext as well as all of the session data.
Not sure if this helps, but it was worth a shot ;)
Richard.
I may be a little late but...
Today I found about the:
System.Web.HttpRuntime.Cache
I know is not the same that a session but I think it's much better alternative that db.
Regards.
I have been asked up to come up with a state management strategy for a ASP .NET / MVC C# 3.5 web app
I have chose to go with storing sessions on a state server - this will be a separate physical box. I am concerned about the time that would be taken to serialize/deserialize objects when storing into sessions...
Does anyone know of a technique to get maximum performance when doing this?
Also would something like compressing information before storing it in session help or would this also result in slower performance times.
EDIT: I am using a separate box for the state server as we will have multiple web servers.
Personally the most common elements here are to work with reducing the amount of information put into session.
Compression MIGHT save space, but it is going to take more CPU time to get it done, more than likely causing either reduced performance or at minimum no net gain. Unless you are talking about REALLY big objects.
Example of Zip Compression on Session, Application, and Cache, used right here at StackOverflow.
Make sure you disable Session State on pages that don't use it. "By default, the ASP.NET session state manager performs two accesses—one read access and one write access—to the session data store in every request, regardless of whether the page requested uses session state." --MSDN Magazine
Be careful you're not trying to prematurely optimize your solution. Before implementing something like Session compression, it would probably be a good idea to conduct a series of benchmarks to determine if something like that is even necessary in your application.
You sure you'll be storing that much data in your session storage? Typical use of a session for a single user is a few hundred bytes!
As for serializing and de serializing, with that kinda small size is negilable.
Of course you'll be expecting more users than that, but still.
If your storing large amounts data in your session, then IMO, your doing it wrong.
Several have pointed out that too much data in session state per-user is a sign of a problem, but they haven't directly pointed at the solution to it: keep a user SQL database and store all the user info in that. Then the session state typically consists of just the logged in user's id. Any other state is probably directly related to the user's current activity, which suggests it can possibly be carried along more appropriately as in-memory cookies or querystring variables. Often this is the better option anyway, so that things to get into a corrupt state when users click their Back and Forward buttons.
Is it possible for ASP.NET to mix up which user is associated with which session variable on the server? Are session variables immutably tied to the original user that created them across time, space & dimension?
To answer your original question: Sessions are keyed to an id that is placed in a cookie. This id is generated using some random number crypto routines. It is not guaranteed to be unique but it is highly unlikely that it will ever be duplicated in the span of the life of a session. Even if your sessions run for full work days. It would probably take years for a really popular site to even generate a duplicate key (No stats or facts to back that up).
Having said all that it doesn't appear that your problem is with session values getting mixed up. The first thing that I would start to look at is connection pooling. ADO pools connections by default but if you request a connection with a username/password that is not in the pool it should give you a new connection. Hint that may be a performance bottleneck in the future if your site is very large. It has been a while since I worked with SQL Server, in Oracle there is a call that can be made to switch the identity of the user. I would be surprised if there was no equivalent in SQL Server. You might try connecting to your DB with a generic username/password and then executing that identity switch call before you hand back the connection to the rest of your code.
It depends on your session provider, if you have overriden the session key generation in a way that is no longer unique, then multiple users may be accessing the same session.
What behavior are you seeing? And are you sure there's no static in play with the variables you are talking about?
while anything is possible. . . .
No, unless you are storing session state in sql server or some other out of process storage and then messing with it. . .
The session is bound to a user cookie, the chances of that messing up in a normal scenario is very unlikely, however there could be issues if using distributed session state.
It's not possible. Sessions are tied to the creator.
Do you want to mix up, or do you have a case when it looks like mixed up?
More information:
I've got an app that takes the userid/password from the login page and stores it in a session variable. I plop it into my connection string for making calls to SQL Server.
When a table gets updated, we're using 'system_user' in the database to identify the 'last updated by' user. We're seeing some odd behavior in which the user we're expecting to be listed is incorrect, and it's showing someone else.
Can you pop in the debugger and see if the correct value is indeed being passed on that connection string? It would quickly help you idenfity which side the problem is on.
Also make sure that none of the connection code has static properties for connection or user, or one user may have their connection replaced with that of the most recent user before the update fires off.
My guess is that you're re-using a static field on a class to hold the connection string. Those static fields are re-used across multiple IIS requests so you're probably only ever seeing the most recently logged in user in the 'last updated by'.
BTW, unless you have a REALLY good reason for doing so then you shouldn't be connecting to the DB like this. You're preventing yourself from using connection pooling which is going to hurt performance under high loads.