I am using the Session object in my code to store the user login which will be saved to the DB.
I want to make sure about the the behavior on session timeout.
If the session times out what can the user do? I guess browsing to different pages does not restore the session? so only choice is to Close all of the browsers and come back in and Session gets alive?
I want to know under what conditions Session won't be alive again.
Also does Session time out fires the Session_End in the global.aspx?
A session is considered active as long as requests continue to be made
with the same SessionID value. If the time between requests for a
particular session exceeds the specified time-out value in minutes,
the session is considered expired. Reference
I believe that you are checking if the user is logged in or not in each page (or in masterpage), so as long as the user is not idle and he is using the system, the session will be updated and no worries.
If the user was idle for a long time and the session was expired, then it is logical to make him sign in again for security reasons.
use this on logout:
Session.Remove("sessionname");
I believe you're not explicitly killing the session by calling Abandon method on the session object in Session_End event.
Logging out of session makes this event to fire.And obviosly the user must be brought to the login page while trying to naviagte between pages.
Using the session to store a validated user's details is quite common. The session times out after a period of inactivity (I believe it's 20 minutes by default but can be changed in web.config.) This is usually desirable because if the user abandons the site (or walks away from their computer) without logging out it will kill (eventually) the session and effectively log them out automatically.
Reading or writing to the session will reset the timeout countdown. So if each web page check to see if the user is logged in all they will need to do if view a new page within 20 minutes and they won't be logged out.
If the user logs out (or the session times out) they don't need to close their browser, just go back to the login page and login again. So for each page that should be protected, check if their session exists and is logged in or else redirect them to the login page.
Yes the session timing out fires the session_end event.
Related
Can you advise me on how to kill somebody's session and make them logout from my MVC app.
My current plan is:
On the start of the app to load a SessionsCache
When user logins - save his session in tblSessions and partially reload the cache (add the session in it without making it call the DB)
Every 30 seconds an ajax will validate whether I have session or not
The administrator will have an interface tool containing all active sessions in the cache and when he kills a session he deletes it from the cache and DB
On the next ajax call the user wont have session and would be logouted
If a user logouts normally the session in the cache and DB will be deleted
Every 30minutes a full reload on the cache would be done
Please consider that my application has OnActionExecuting() overriden function which checks if the user has session and if not loggouts him.
But this happens only on action execution and if the user doesnt click anywhere (afk) he wouldn't be redirected to home page. (considering maybe the ajax call to check session is redundant?)
Also i want to clear user session when he closes the browser/tab without using the LogOut button but I am not sure how can this happen
There's a few issues with your proposed solution that makes it unworkable:
Both sessions and auth employ client-side cookies to manage their status. The server can only invalidate the authentication/session. It cannot actually "log out" a user directly, because that piece is not under direct server-control. In other words, you can set up something that says that a particular user should be logged out, but that user will not actually be logged out until they attempt to make another request and some check is performed by the server which then affects that status change on the user at that time.
Sessions employ sliding timeouts. That means any request the client makes will reset the timeout of their session. In other words, if you long-poll the session status every 30 seconds, the user will effectively have a perpetual session that will never ever expire.
Sessions are intentionally anonymized. For security reasons, the client's only link to their session is the cookie with their session id. This prevents a certain level of session hijacking by making the cookie a must-have component in a successful attack. With things like the Secure token, then, and of course utilizing SSL on your site, you can effectively prevent that cookie from being usable in any other context than the client it was assigned to. The long and short is that there's not really any way to figure out which session belongs to a given user outside of direct contact with that user.
Cache is by nature volatile. You can say that particular key should have a lifetime of some period, but that's merely a suggestion. There's any number of different factors that could cause a cached item to be destroyed, most completely outside of your control.
Given all that that, you must approach this from a different direction. My suggestion would be to have a separate table where you track logins/sessions, in a generic sense. It would basically be a kind of log. When a user logs in or creates a new session, you would add a record to this database. If the user's auth or session expires, you would update the appropriate record. If the user deliberately logs out, you'd delete the record or otherwise mark it as inactive. As far as your admins go, they would then manage this table, removing or marking records as inactive.
Then, you will have to add some logic around your site actions to account for this table. You could create an action filter that checks this table and performs any necessary operations. For example, if the user has been "signed out" by an admin, the action filter would read the appropriate record from this table, see that the user had been signed out, and then affect that change by actually signing the user out.
Since long-polling will cause the session to never expire, you would essentially need to manage your own timeout. For example, you could record the time the session was created in the "log" table, and then compare that time with the current time on each subsequent request (including AJAX). Again, you could employ an action filter for this purpose. If the session is "expired" based on your timeout, then you could manually destroy the user's session.
There's plenty of other things you'd need to add or account for in this way, but hopefully that gives you a good framework to work from.
We have a website that has a 20 minute session timeout and our users want a 10 minute session expiry warning. At the moment we're using a control which kinda does the job but it isn't AJAX aware and so pops up even if the user has been doing stuff.
I have an idea to get around this by just polling the server every 2 minutes to find out how long the user has left on their session. But after research i can not find out if its possible to say "This request shouldn't refresh the timeout", which is crucial as the act of polling would inadvertently refresh the session timeout.
Is this possible, or am I going about it the wrong way?
I think the only reliable way you can do this is to modify your ajax javascript to extend the timeout on your existing script.
You could use the disable session state for a page then modify your app to store the last access time for a user in the db. poll the session-less page to find out when the user last did something.
Either way you'll have to make extensive changes across your app.
If your session has a fixed 20 minute expiry, then it won't get extended by refreshing a page. However, if you want to have a script on your page to alert users of their imminent session expiry, then you'll need to set a client side script (presume Javascript) and kick it off on page load?
<script type="text/javascript">
function alertSessionTimeout(){ alert("Your session is about to expire. Please refresh the page.") }
window.setTimeout('alertSessionTimeout', 10*60*1000);
</script>
what about TWO web applications accessing the same database? in the first, the main, application you write last access time to database, and the second application is polled via ajax to get inactive time base on last access time...
In polling the server you see how long is left you would be resetting it back to 20 minutes. You would need to make sure the request does not attach the session cookie to prevent this. In doing so you create another problem in that you can't access the user session.
An alternative is just do in JavaScript page load using SetTimeout.
It seems that some people are confusing Session state with Forms Authentication ticket expiration. Session state has an automatic sliding expiration - if session is set for 20 minutes and after 19 minutes of talking to your friend in the office, you request a page, you get another 20 minutes.
This is an old question, but I have a similar problem and had this idea for a solution.
Upon each page request that uses the session, your session gets refreshed. Into the application cache, put key=sessionId and value=DateTime.Now.
Create a web service (.ashx or what have you) that does NOT use session state, but ideally is authenticated using Forms Authentication or some other authentication scheme. Your javascript, which is counting down the time until session expiration, will call this web service shortly before the session expires to see if the session is really going to expire.
I'm thinking the web service should return something simple like a 2 if the session is expired, 1 if the session is about to expire, or 0 if not. Return random [0,1,2] if the service is called by a user with an unknown or invalid SessionId cookie -- this would hopefully prevent valid sessionId discovery by an attacker who gets a Forms Auth cookie.
I investigated decompiling the built-in SessionProvider to see if I could access the session to discover the expiration without triggering a refresh. But doing so is dependent on the type of session provider being used, so if you ever move from, say, SQL Server session provider to Redis, you have to rewrite it.
I wanted to stop multiple login of the same user. So, I created a table which keeps track of users who have logged in. When they log in, the data will be entered in the table. When they click on logout, data and session will be removed.
The problem is, when they close the browser window without logging out, they won't be able to login ever again.
Is there a better way to handle this?
You have to delete inforamtion in table on global event Session_End in global.asax.cs file
protected void Session_End(Object sender, EventArgs e)
{
//delete from database where userID = Session["userID"]
}
If we are speaking about 'StateServer or SQLServer' session mode than:
Session_End event will fire once you call Session.Abandon(). There is job ASPState_Job_DeleteExpiredSessions on sql server, that expire user sessions if user not logged out using logout button. This job call DeleteExpiredSessions stored procedure, so i suppose you should place some logic(remove logged user) into this stored procedure.
from documentation:
You can handle the Session_OnEnd event
by adding a subroutine named
Session_OnEnd to the Global.asax file.
The Session_OnEnd subroutine is run
when the Abandon method has been
called or when the session has
expired. A session expires when the
number of minutes specified by the
Timeout property passes without a
request being made for the session.
The Session_OnEnd event is supported
only when the session state Mode
property is set to InProc, which is
the default. If the session state Mode
is StateServer or SQLServer, then the
Session_OnEnd event in the Global.asax
file is ignored. If the session state
Mode is set to Custom, then support
for the Session_OnEnd event is
determined by the custom session-state
store provider.
You can use the Session_OnEnd event to
clean up session-related information
such as information for a user that is
tracked in a data source by the
SessionID value.
Keap you session time out short and when session is diposed log user out automaticly
Just keep one session variable saying true/false depending on login status. True - user is already logged in, False - not logged in.
In many cases I have a User object saved into the session, so I just check it against null, which just returns the authenticated user or null (anonymous).
Simple enough and without DB involved.
EDIT:
If comments below understand the problem correctly then please despite this answer. I was referring to the situation when you don't want an authenticated user to log in again during the same session.
i want to create a global session which will stay active until and unless we manually kill it. how to do this in asp.net with c#
what i am doing is
HttpContext.Current.Session["UserID"] = someValue;
but in this way the session is lost after some time.
You can set the timeout in web.config under system.web -> sessionState -> timeout. Not sure if you can have an infinite session though.
Also, you might be interested in the Application object which stores things in the "application's session" instead of the user's. Comes to my mind because you speak of a "global" session.
What's the application for this? Sounds like you're actually trying to use the session as a persistent storage, which will however only seemingly work even if you manage to set timeout to never or 5 years or whatever - because sessions will be "timed out" once the application is restarted. You might still get around that, but you might be better off looking for real persistence solution like a database. I may be totally off guessing your application for that of course.
Store the data in the Application state rather. It will stay there till you remove it, or the app dies/recycles/ends.
Usage:
HttpContext.Current.Application["Foo"] = "bar";
As nicolas78 says use session timeout configuration property to control the session expiry after user inactivity. In case, you are facing a requirement where session should be active as long as browser is open, there are two ways -
Use cookie to store some token and then re-construct your session state using the token if session gets expired. For example, user details can be recovered from user store if user id is stored in token. At worst, you may have to move your entire state to the database.
Keep the ASP.NET session state but keep it alive by firing AJAX requests from browser. I would suggest to fire such request after n/3 interval where n is your session timeout (ensuring at least three requests are made so even if two gets lost or falls on edges, one gets through).
Perhaps you're after profiles?
http://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx
Profiles live beyond the session and are usually used to store per-user settings that the user can edit, such as their contact details and application preferences.
Profiles can be used with both anonymous and authenticated users. When an anonymous user signs in, their anonymous profile can be migrated into an authenticated profile (i.e. one that is attached to their user name).
Good walkthrough here: http://quickstarts.asp.net/quickstartv20/aspnet/doc/profile/default.aspx
Guys, I am trying to make a website that keeps a cookie active, so long as the user is active in the site. My idea was to create a cookie on the main page of the site, like so:
HttpCookie cookie = new HttpCookie("KeepAlive","1");
cookie.Expires = DateTime.Now.AddMinutes(20);
Request.Cookies.Add(cookie);
If I have this code in my Page_Load event on every page, this should keep refreshing the cookie. If, after 20 minutes, the cookie expires, it will kick them back to the main screen. I just want to make sure I am going about this the right way.
Thanks
I think you should look at using session for that. With Session, you can set a timeout (20 minutes by default), and the rest will occur automatically (updating the active status, etc).
EDIT (more on Session):
By using session, the site user can be identified throughout their experience. This happens automatically, without any need for the developer to code for it or to test that it works.
Session is stored on the server, and is therefore safer (users can modify their cookies)
You can run code at the start, or at the end of any session (using a global.asax file)
Sessions can be setup as cookieless (users may have cookies disabled)
You can store c# objects in session variables so that they are available through the active session (stored in server memory).
I can't think of any more advantages in this case. I invite others to leave comments with their thoughts.
If you really want to use cookies for this, Yes, You are going the right way.
You need to add the cookie to the Response object, not the Request object.