6

We have a web-application developed using struts2, spring & hibernate.

The application needs a functionality that one user can login from only one browser.

Say if user x, is logged in on pc-1 browser ff, then he cannot be logged in from any other place.

I tried it by implemention session map and store the sessions in global map, but this fails when user logs off and tries to login again.

Even it fails critically if the user does not logs off and session time-outs, but the map is not cleared.

Any better idea to implement this functionality.

We do not want to obstruct the user to login but do not want users to exploit the application by allowing him to share the creditionals and allow multiple users with same login to happen.

Amol Ghotankar
  • 2,008
  • 5
  • 28
  • 42
  • Possible duplicates: [this](http://stackoverflow.com/q/1932091/248082) and [that](http://stackoverflow.com/q/3670991/248082) – nobeh May 28 '12 at 10:23

8 Answers8

14

Since you are already using Spring, I would recommend you to integrate your application with Spring Security.

Spring security lets you define maximum sessions allowed per user concurrently.

<session-management>
        <concurrency-control max-sessions="1" />
</session-management>

If set when user having valid session tries to login again it will inform user that maximum concurrent access is set to 1.

Read more at the reference documentation of Spring Security: v3.2.x, v4.2.x or v5.1.x.

If spring security is not an option for you then:

  1. Use a SessionInterceptor which will check for session validity, if session is valid it will check if user is already logged in to the application (for this you will have to maintain session somewhere for eg database for every successful login), if valid login is found, redirect user again to login page with custom message, or logout already valid session and then redirect him to login again. If you logout earlier session it would mean any successive action in that browser session will have to deal with invalid session.

  2. If case you are also using Servlet in your application then Interceptor wont work for you, in this case you should use a Filter and follow the same steps as detailed above for Interceptor.

mhadidg
  • 1,503
  • 17
  • 29
mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • what if user opens multiple browsers and next request hits to another server in cluster? I don't think there is a silver bullet to solve this – Teja Kantamneni Apr 11 '13 at 15:05
  • @TejaKantamneni if you use a database to capture valid login it will work irrespective of which cluster you hit. – mprabhat Apr 15 '13 at 07:34
  • @mprabhat, agree that it will work to some extent where every user genuinely logs out of the system. Otherwise, we have to start adding jobs to clean up the stale sessions from db and so on – Teja Kantamneni Apr 15 '13 at 12:44
  • Yeah there will some cost to maintain it, can't help – mprabhat Apr 16 '13 at 06:21
2

The best solution is to log-off user from other session when he logs in in new session. It is often that user would not logoff when closing browser and restricting him from logging in other window would be the pitfall.

Automaticly closing any previous user sessions is good, because in normal usage, it is no problem, but when sharing login and password, no two persons can work simultanously with your application.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
1

At the login give the user a generated ID/cookie (sessionid suffices) stored with the user data. If a user does a request to the server with an old ID/cookie, say that he logged in elsewhere.

The other way round, forbidding the new login attempt, has its drawbacks - as you've experienced.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
1

Create a map. At the time of logging check that user id is present into that map or not. If its not exist then put user id into map, at the time of logout remove that user id.

Sachin J
  • 2,081
  • 12
  • 36
  • 50
0

To be honest I would revisit the reasons why you have to restrict a user to a single login. Whilst preventing them from logging in from two different browsers is easy enough - any of the suggestions provided would work - with the Spring Security option being the easiest to implement if you can - they all break down when your user opens a second tab in the same browser. That is considered to be part of the same session.

user497087
  • 1,561
  • 3
  • 24
  • 41
0

Maintain user stack in servlet context,as it will be one for web container.perform a check before user getting logged in, if user name found in servlet context redirect him to login page.

user3244376
  • 11
  • 1
  • 8
0

All you should do is add a field in database userprofile table saying: alreadyLogin. If user logins, make it Y. If user logs out, make it N. Now every time when user tries to login from new location, check this value and prevent login if Value is Y.

Aakash Patel
  • 549
  • 5
  • 19
  • I think the other way around is better - if a new login is made, then close the old ones. I don't think I've ever seen a solution, where new logins are prevented. – nelion Mar 23 '21 at 10:15
0

As many said, you can have a Map<String, User> (static Map or better an attribute in ServletContext) of (sessionId, user) of active users.

When a user tries to login, first check the existence in theMap.values(), and if it is okay add it to theMap.

Instead of removing from theMap on logout, implement a javax.servlet.http.HttpSessionListener, and on sessionDestroyed method, remove the item from it (the parameter of the method gives you the sessionId). This way if a user closes the browser, after session timeout period, it will be removed automatically.

On logout, invalidate the session, so it will be destroyed, and again this listener get executed.

Don't forget adding the listener to your web.xml.

Amir Pashazadeh
  • 7,170
  • 3
  • 39
  • 69