Restrict Multiple Login of same user across 2 Web Applications - servlets

We have got requirement to restrict concurrent login of same user across 2 Web Applications.
We have 2 Web Applications for example: WebApp1, WebApp2.
User: Dashboard
If Dashboard user is logged into WebApp1 then the same user is not allowed to login to WebApp2 instead show error message on second login.
Tried Solution:
Block 2nd login with same user id if there is an active session and show error message to user.
The idea is to maintain user id, Application Name and session id in DB. On second login of same user check if record exist in DB table against the user id then block 2nd login and show error message to user.
Clear the DB record (UserId, Session Id, and Application Name) in following
scenarios:
Logout
Session Timeout
Restart of Application.
Not Sure how to handle below scenarios.
Close Browser.
Browser Crash
System Crash
If 2nd login request is from valid user then Admin should able to Invalidate the session of first login as this user is attacker.
what is best way to invalidate Http session of WebApp2/ WebApp1?

If you really need to know the state of the first session, I would skip trying to manage sessions in the server, and instead maintain a heartbeat from the client. Have the client make a request every 5 seconds to the server which updates a "Last Seen" record, which includes their IP address and which app they are from, and whether "Last Seen" was a logout event.
Then the other app can interrogate "Last Seen", and if it's more than 5 seconds (I'd actually bump it to 10 for the interrogation), or a LogOut event, assume that the first session went away, and that they are free to log into the second application. If "Last Seen" is less than 5-10 seconds, bump them both out and alert the admin with both the IP Addresses to decide which one should be killed.

In addition to what you have, you could save last activity time in your session DB, and update it, when there is a session update, how often ( every request or once in 5 min for example) it depends on your requirements. Then in case of app/browser/system restart, you log in user, even if record exist, if it is older that session timeout. And you can have admin user that can manually delete entry if required.
The other solution would be to always log in new app, and logout the old one. But that would require introducing additional logic in the application to check if session is still valid.

Related

log out a user logged in from different browsers/machines using forms authentication

Consider the case of forms authentication with persistent cookies.
If the same user logged in using two different browsers or two different machines, when user logs out from one of the browser/machine, wouldn't still he be able to login from the other browser/machine?
Usually, how do web applications handle this case?
I have to agree with Srinivas for the most part. Here is my take on the subject
On Login create an HTTP Only cookie with a guid generated at login this will be your browser/computer key. Closing browser will remove cookie
Get user id
Persist in the pair in user table ex: user:a, key:12345
On subsequent requests authentication algorithm after user has been authenticated
Get the last used key in the db with current user id
Check that the cookie is present, if not then completely unauthenticate
Check that the cookie value is the same as that in the database, if not then completely unauthenticate
With this method any subsequent login will cause a required reauthentication & invalidate any other authentications. In effect forcing the user to use only 1 browser/computer
I usually do it this way : I have a session column in my user table(in database) When the user logs in I store the value Y in it.I change it to N when he logs out.Every time the user tries to log in, I check the value in the corresponding session column and if it is Y I tell the user that he is already logged in and if it is N then I allow the user to log in. But we have to be careful and set the value to N when the user logs out or closes the browser.
Forms Authentication with cookies (regardless of whether they are persistent or not) is browser session based (persistent cookie would of course work across multiple sessions of same browser (on same user account on same machine). So two browser sessions (or two different browsers or browser on two machines etc) would be treated as different scope as far forms authentication is concerned.
So user can make multiple login from different browser sessions and logout in one will not affect other. Its is up to web application whether to allow multiple concurrent logins for same user or not. For example, online banking sites would restrict to only one user session - so if user logs in from different session then earlier session is invalidated (i.e. user is logged out). One has to write custom implementation in ASP.NET to do so - typical implementation would make every user session entry into database (typically required for audit purposes anyway) - so whenever new entry is added, a check is made to see if there is any active session for same user and if yes then that session is marked inactive. Every request would check if current user session is active or not, if not then it would flag such message to user.

Only one user of asp.net web application at time

I have a specific request to allow only one user to use asp.net application at time because of web application nature.
I've tried to implement this by using Application state using some sort of session counter which is incrementing on session_start and decrementing on session_end, but the problem is that session starts immediately when application display login form (because of form authentication).
If first user browser displays login.aspx, session_start in global.asax is called and sessioncounter is increased for 1. SessionCounter now equals 1.
If another user browser also displays login.aspx, before first user is authenticated, session_start in global.asax is called and sessioncounter is increased for 1. SessionCounter now equals 2.
My idea was to authenticate user only if SessionCounter <= 1. But in upper described case we will have a lock becase sessionCounter is already 2 and if first or second user tries to login, it will not be able to authenticate because sessioncounter is greater then 1.
The second problem is when session times out before authentication times out. If first user's session times out, and in that moment second user tries to login second user will succeed to enter application. But what happens if first users makes some postback because his auhentication has not timed out. New session will be started, session_Start event handler will be called, session counter will increase, but user will still be logged on because user is already authenticated.
What is the best approach? Is it possible to avoid Application state because ASP.net 3.5 has known issue of calling session_end immediately after session_Start if session object is not used.
I've thought about using some database flag, but then I'll have another problem. What happens if user closes browser before resetting this flag. I can insert some timestamp when raising flag. Then I'll have following scenario:
First user logs in. DB flag is raised and timestamp is inserted. First user forgets to log out and only closes browser.
Second user tries to log in. DB flag is checked and because it is already raised he can not access application. If I set one more condition to check if some period of time has passed from last inserted timestamp, for example 30 min, I could allow second user to access application regardless of DB flag, but that is not good solution becase I'll have to wait for this period of time.
What is the best solution for this problem? Is there any global variable available in .net framework which allows us to check total online user count (I am not using membership provider)?
You should be able to do this through IIS by limiting the number of connections and adding a custom error page to handle 403.9 (Forbidden - Too Many Users) errors.
Limiting Connections to Manage Resources (IIS 6.0)

How to tackle this session problem in ASP.NET,VB.NET?

How to tackle this session problem in ASP.NET,VB.NET?
The following requirement are there:
When the authorized user logs into the system that user is not allowed to login from another computer or in different browser other than that user is using right at this time.
The remedy we applied was: We have kept "Is_Loggedin" as a column with data type "bit" in a mst_vendor as a table name. When a user logs in we set the flag, Is_Loggedin, to "1" and each time when someone tries to log in using this account, the system is showing the error "The user is already logged in.".
When the user logs out it turns to "0" as the logout procedure calls as soon as the user clicks the log out button.
Problem scenario:
When the user closes the browser the flag remains the same, that is, "1".
When power gets off, it remains the same as "1".
If the session timeouts after a predefined value it remains the same.
There may be different scenarios other than this.
Is there any way so that we can store this internal flagging for the user's login status using the application object?
It may improve efficiency of the system and also eliminates the above problematic scenarios.
You should use the Global.asax file and use the Session_End function.
Session_End: Fired when a user's session times out, ends, or they leave the application Web site.
Store a datetime as another column next to the bit, and update it each and every time the user requests a page.
When a new user comes along with the same credentials and the bit is "1" you can check the datetime, and if it was a while ago you can be certain the user is no longer there. So let the login go ahead.
You could keep a pulse going in script, and when the pulse times out, consider the user finished with that session.
The benefit to this is that you can tell the difference between the user sitting idle on the site and the user leaving the site.
From a very top level view, here is what you can do
Use Cache with SlidingExpiration.
Everytime a user attempts login, check the cache with his username as the key. If an entry exists in the cache, you can say that user is already logged in and deny login.
If the key is not found, allow login and create a new key in the cache as the username and set the sliding expiration time. (This should be carefully chosen as this would be the duration, the user wouldnt be locked out after the browser is closed and user attempts to relogin.)
In the Application_PreRequestHandlerExecute handler in Global, check if the user is currently active (you can use sessions for this), reset the sliding expiration time for the user. This way, with each page request the cache expiration time would be reset.
If the user closes the browser and moves off, the cache would expire after the set period of time, and would free the user to log in again.
if in case the user attempts to login again before the cache expires, the user would have to wait for some time to let the cache expire.
if the user logs off properly, you can remove the cache entry on the logoff event such that user doesnt have to wait to relogin.
The Sliding expiration timeout can be synced with session timeout to emulate the actual session timeout for the application.
With this approach, you would also save on a lot of database round trips to update/check the user status and this would work irrespective of the hosting enviornment or the session modes.
Yeah, a script would be a good idea. Just set the session timeout to be 5 minutes instead of 20 and then write a method into session.end in the global.asax file that updates the database accordingly.

Multiple log-in problem

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.

Kill ASP .NET user session from admin session

I own a gaming website. From time to time I need to suspend users for different reasons. They cheat or they are bad users with bad intention. After suspending users, they can't login anymore on my site, until the suspend period expire.
However, after suspending an user he still can acces the site, can chat with other users, can create forum posts, can do everyting, that's because he remain logged in on the site. I can't do nothing to this and most of the time I need to restart IIS in order to get rid of bad users.
Is there anyting I can do to kill an user session from my ASP .NET session ? I am against using SQL to store user session variables.
I prefer to check an ASP .NET session/application variable on every user request, and if that variable contain the ID of suspended user, to logged out him immediately.
You can't acess the session in the way you want. What you could do is keep a list of suspended users in the application cache. On each page request, and each login attempt, you can do a lookup on the list to see if your current user is suspended. If he is, you can then log him out and abandon his session, or prevent the new login.

Resources