I'm developing a web tool using JSP, where there are many users of multiple kind (i.e. administrators, guest, write-enabled users, ...). Since this will be a subscription based system (i.e. user pay for a 3/6/12 month subscription), I need to enforce at most 1 login per user at the same time. For example, say Mr. John Smith subscribes to this system; I don't want him to give his login info to a friend of his so that they'll both be using the system from 2 different computers at the same time. How can I manage this situation? Thanks
When a user logs in you will want to invalidate any other login they might have at the time. This means doing a check on every request that is made, but you should have that for basic validation anyway. For example you can check the IP address they are accessing from, or the servlet session id, etc. These are all good things to keep track of anyway, especially for fact/report logging.
Then you can use annoyance of being logged out to enforce your policy, without making it impossible to go from one system to another and continue using the interface.
Use the aforementioned fact/report logs to analyse logins to see if any appear to have usage patterns that don't match a typical single user - sessions swapping frequently between two or more computers for example, especially at similar times.
- When a user logs in, store the
HttpSession.getId()
for that user. This could be in an application scope Map from user names to session IDs, or in the database. - For each subsequent request, for a logged-in user, check that
request.getSession().getId()
is the one stored for that user. - If the request session ID is not the one stored for that user, then it must be the ID of a newer session, for a later log in with the same user name. In this case, inform the user that another log in has taken over, and call
request.getSession().invalidate()
to log out the user.
The main thing to remember is that given the stored session ID for another session - not the current session - you cannot cancel that other session.
Also, unless you clear the stored session ID after a time-out, you cannot reject the second log in attempt because you cannot tell whether the first session is still active.
I do not know which, if any, framework you're using (you only specified JSP). But, if the rest of your application is taking advantage of the Spring Framework, this feature is already implemented in the ConcurrentSessionFilter from the Spring Security project. It supports several ways of detecting and dealing with concurrent log-ins, including the one suggested by Peter Hilton, above.