How do i keep checking if a user still is active, for like every 1 minute? I need to know which user is currently active and who is not! I'm not using ASP.NET membership provider!
Lets say, maximum 3 log in are allowed for one user to log in simultaneously from 3 different locations, if the same user, which is the 4th log in, try to log in from another location again, i would like to block the 4th log in.
I have few issues regarding this as well! If the user unplug the connection cable or close the browser, how do i figure out if the user is still active?
I would need more detail about exactly what you are trying to accomplish, as you have asked a fairly vague question. However, I would think the best way to determine if a user is active is to check if their ASP.NET session is still alive. There is no "accurate" way to test if a user is still browsing your site, because they could be sitting there reading, or be AFK, or be in another program on their computer...dozens, if not hundreds of scenarios could exist on the client side.
However, the user's ASP.NET session will only live for a specific period of time between each activity from the user (GET, POST, etc.) Usually after 20 minutes, ASP.NET will clean up the users session, and when it does, it will fire a Session_End event that can be handled either in Global.asax, or with a custom HttpModule. You would then be able to flag that user as inactive in your own database, send an email, or do whatever it is you need to do.
You can use the HttpResponse.IsClientConnected property to check if the user is still conncted to the session. For details see this -->
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.isclientconnected.aspx
Alternatevely, you can set a counter at Session_OnState at global.asax to check for the active session available and do your stuff based on that.
Related
This question applies to both ASP.NET webforms and MVC apps. I have a checkout process where there are two forms Form A (address page) and Form B (shopping cart page). The normal happy path works where the customer completes the Form A and then click submit button which takes him to the Form B.
The customer can accidently visit the Form B without ever visiting the Form A or completing the information. How can I find out whether the customer has completed the Form A if he access the Form B directly? If he has not completed the Form A, I want to redirect him to Form A. Is there a ASP.NET framework object that I can use for this purpose?
The only foolproof way is to save something to a database that indicates that the particular user has completed Form A. This could be actually storing some entity that is created by Form A or just some sort of log. The key is that you'll need to associate with the user, which means the "user" must actually have an account and be logged in. If it's anonymous, there won't be any real way to track them.
With this set up, then, you'd simply check in your database that the user has a record indicating they've completed Form A in the controller action for Form B. If nothing exists, you redirect the user to Form A. Otherwise, you allow them to view Form B.
And alternate approach is to use Session or set a cookie to indicate that Form A has been completed. There's pros and cons to both of these, and neither is foolproof. With both Session and a cookie you can track anonymous users, so you don't have to force a login. However, Session is not a permanent data store. By default, it will expire after 20 minutes of no activity, and even if you bump that timeout up significantly, it's always going to be finite.
Additionally, depending on the session store you use, it can also be very volatile. In Proc is the default, as it requires no configuration. Everything is stored in memory, but if the server restarts, App Pool recycles, etc. then all the session data is lost. It is possible to configure it to use something like SQL Server, though, and that would be very stable. Either way, you'd still have the timeout issue to deal with.
With cookies, you can set a far-future expires cookie that would effectively be permanent. However, cookies are stored client-side and can be removed by the user. They can also be manipulated (either created manually or modified). This means if a malicious user figured out how you were tracking whether Form A had been completed, they could basically fake that, and make your site think they had completed Form A, when they had actually not. Now, whether any one would care enough to do that is an entirely different matter. Still, it's something to consider.
Finally, both Session and cookies can effectively be disabled by the user. Session actually uses a cookie to store the session id, so if the user disables cookies in their browser, neither approach will then work.
Your best bet is still forcing a login and storing something in a database to indicate that Form A has been completed by that authenticated user. However, if you can deal with or mitigate the downsides of using Session or cookies, then those might be viable options.
I have built an ASP.Net MVC site using Forms Authentication for a client.
Recently, they have requested that an authenticated user be restricted to a single browser session. That is, if the user raises a new browser instance, or opens a new tab on the original browser window, that he/she be logged out of the original. They insist on the added security.
Does anyone know how I might approach this? Thanks in advance.
Personally, I would push back and ask exactly what security this is bringing. Maintaining state like this counter to web architecture and is only going to bring you and your users grief.
Here is what I would do if presented with this problem:
Store the username of the user in your database (i.e. LoggedOn table).
When a user logs on, check to see if their username is already present in the LoggedOn table.
If the user isn't already logged on, insert a row into the table with the username and the current time; otherwise present the user with a message informing them that they can only log into the system from one device at a time.
Include logic to expire and delete the rows in the table if a user's session expires or if the user logs out.
First a disclaimer: I'm no expert in web programming.
Perhaps you might try a system where every user interaction requires the submission of a random value that's been generated for that page (much like what's used for CSRF protection.) That key could be kept under the user's session information on the server, and if a page is ever requested without the correct key as a URL parameter, the session is invalidated. The URL from one browser won't work in another, either, since once a URL is gone to, the user's session key has changed. The only way for a user to transfer a session between tabs would be to copy the URL of an unclicked link and paste it in a new tab's address bar. Switching browsers would be even more complex assuming that ASP.Net uses a session cookie: the user would have to transfer the cookie from one browser to another. Going back would also fail, as all the links on the previous page, and the URL for the page, would carry an incorrect session key.
Also, for reference, I believe the US Gov't TreasuryDirect site works in the way you've described, though I've never looked at how they manage it.
Thanks, people for the suggestions. Each had strong merits, however I had to take a hybrid approach. I found an incredibly simple suggestion from this post.
I implemented table of active users as Karl suggested as well. This will give the client the ability of deactivating the user on demand.
Thanks again.
Think of it as one active view at a time instead of one browser or tab. Or convince the customer to view it this way.
You can always issue a unique cookie for the browser session (ASP.NET Session) and allow communication to the latest cookie issued effectively making only one session active at a time, and therefore rendering other open sessions (browsers, tabs, etc) useless with the app by disallowing them communication any longer or serving up an error page for them. To do so you have to recognize who the user is and authenticate them against your app. This is half the puzzle and will force the user down to use your app in only a single browser at a time on their machine.
The other part of the problem is to pare down the windows and tabs that are part of the same browsing session of that browser, to allow only one view to be active at a time. To do so you can issue a unique sequential ID to the viewstate of each page for postback to the server to uniquely identify that page apart from other pages sharing the same session state (whether that page be in a browser tab, a frame or new window, etc). Or a code of your choice that's traceable. You then know which page is posting back within the session and can disallow others or deactivate previous ones by, again, shutdown down communication in some manner or serving up an error page, etc.
A new browser instance or a new tab may or may not be part of the same browsing session depending on how the browser is configured. I believe, for example, IE provides a setting that allows the behaviour to be set of whether a tab opens in a new process or session or shares the session. You won't necessarily get expected consistency across browsers to rely on for this feature, therefore you need to take programming steps to reign it in, like those described above.
You can additional steps like disallowing the user to be connected from a different IP# at the same time.
We have a web application with feature for logging in with credientials
The important requirement is once the user logs in he is not allowed to login from any other system or even another browser on same system
We used following solution which is mssql based : We have kept " Is_Loggedin" as a column with data type "bit" in a table. when a user logs in we set the flag as "1" sowhen someone tries to log again ,the system is showing the error "The user is already logged in"
When user logsout bit turns to "0"indicating user logged out.
However this logic is failing in following scenarios
Problem scenario:
When user closes the browser the flag is "1"and user is locked in or situations when user gets system problem and unable to log out
Is there a better logic to handle this requirement?
While the user is logged in, you could have a AJAX call that pings the server every 30 seconds that the user is logged in. Have a column Is_LoggedIn, and Last_LoggedIn for the date/time when they last sent that AJAX call. If it has been more than, say 1 minute, allow the user to login from another system.
You will also have a problem scenario if the user leaves their browser open for more than the session timeout period, usually 20 minutes. Then they will get logged out on the next request, but not be able to login again because of that is_LoggedIn set to 1. You would be better off doing some sort of time-based solution because keeping track of whether the user is still actively using a website is a very difficult problem because of the many ways they can leave the website without actually logging out.
If it is absolutely critical to avoid any chance of the user being logged in multiple places, you could also force all other places to logout automatically when the user logs into some new place.
You can update 'Is_Loggedin' flag to 0 at session_end event of global.asax.
session_end event is always call. session _end event call when session_timeout is expire.
in the global.asax code behind I believe there is an even for session end. You could tie into that method and set the user's Is_LoggedIn flag to 0. You would then also need to tie a user to a session key to be able to track a user's session.
Edit:
Also, the use of a session cookie or a normal cookie may help if the user closes their browser. The cookie would authenticate them upon re-opening the browser window; however this has a potential security hole if the user is using a public computer.
You could be to log the user out after sometime of inactivity (say 30 minutes). This way if the user closes the browser without logging out he will be able to log in again after 30 minutes.
Use Session_End as Pankaj suggest to make sure that the user's bit is set to 0 when logging out.
The issue with system failures is another problem. Maybe this could do the trick: When the user log in, the store the user's session ID in the database. When the user logs out, then clear the session ID. Every time the user makes a request you verify that the session ID matches the one stored in the database. If that is not the case, then invalidate the session, so that the user is logged out.
This should happen: If the user signs in, in another browser, the session ID would be updated. If user then goes back to the first browser windows and clicks on something, that session would be invalidated, and the user would be signed out automatically.
I am trying to find out in my asp.net application the users that are currently logged in the application by searching on the session info. Currently, I am only able to see my current session, but I cannot find out if there are other users using it. Is there a way to see if there are other users using the application by looking at the session information
Session state is per user - Application state (global) seems to be what you're looking for.
There are 2 hashes Session and Application, in which you can store key-value pairs.
A way to do it would be to update Application[UserNamesList] whenever there is a successful login. This would then be visible to all users. Application state would however be lost whenever the App Web Server recycles or restarts... but that shouldn't be a problem in this case.
A session is supposed to only give you information about the currently logged-in user.
If you need to keep track of all logged-in users, you could consider writing the users into a global variable. Here is info on how that works. Note that sessions expire. You would have to write, for each user, the time the user was last seen (i.e. each time they hit a new page, update their record). When the time they were last seen is greater than your session timeout, it's safe to assume they are no longer logged in and you can remove them from the list of current users. If they just up and close their browser, you will not be alerted and you will still think they are logged in even though they are not.
How do I limit the number of users to a web application.
You may want to limit the web app to only handle say 20 users at a time. Our company sells applications based on a number of licenses, but we are not sure what the behaviour could be in a web app.
I have seen some suggestions saying you can flag a user account as "LoggedIn = True" when a user has logged in. Then each new successful login attempt checks the number of "LoggedIn = True" records. If it exceeds the limit, then the user is rejected.
How will unexpected input be handled in this case? What if:
The user doesn't click logout, and closes the browser
The browser crashes, and the user does not get a chance to do logout
Network connection breaks, electricity on the client goes off etc etc.
All the above will still have the "LoggedIn = True" flag set and contribute to the number of logged in users. This may unintentionally block out genuine authenticated users.
I am looking more for ASP.NET solutions if possible.
Assuming your user authentication is somehow session based, then the answer to all your "unexpected" cases (which will actually be the norm - people rarely seem to log out of web applications) will be that those user slots become free when the session times out. So you'd need to investigate usage patterns of your application. If you get a lot of people logging on for a couple of minutes, but no more than that, then a 30 minute session time out would mean very few people actually get to use the application.
The fundamental problem is that web applications are inherently disconnected, so you can't monitor what a user is actually doing between requests for a page. Normally, you'd sell licences for such an application for specific users (so if a company buys 20 licences, that would give them 20 user names and passwords). Then you could certainly prevent multiple logons by the same user name and password, by either refusing the second logon or deactivating the previous one (which is probably the better approach in case someone has genuinely moved from one machine to another without logging off for one of the reasons you outline).
The most common solution is to have an activity timer. You can assume that an active user will make at least one request within "X" amount of time -- say 5 minutes or so.
You can enforce this by putting an ajax-style async request triggered off a timer that starts when the page loads. For example, if your'e assuming that all active users will make at least 1 request every 5 minutes, then each page will request an empty (but no-cache) page every 4 minutes. That way, as long as they have the browser window open, you'll always have activity from that user. Again, this is handled by asynchronous requests, not by any sort of reload directive. This makes it absolutely transparent to the user.
As an added bonus, see if you can make that ajax request pull down some useful information, rather than just enforcing licensing limitations.
As David points out the main problem is to differentiate between idle users and users that have left your application.
A possible solution would be to keep a low session timeout (say 1 or 2 minutes) and using a callback function to keep the session alive for idle users. Then you could increment a counter in Session_Start and decrement it in Session_End and use it to keep track of the number of active sessions. If the number of active sessions goes beyond your limit you would redirect the new user to a page that abandons the session and tells the user that you have too many visitors at the moment.