• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Preventing Multiple Logins

 
Ranch Hand
Posts: 100
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there,

I know the topic here might sound like it should be in the servlet group, but bear with me.

It sounds simple enough, but I'm trying to implement a mechanism to prevent the same user logging into our distributed web application simultaneously.

So, given the scenario...
- user A logs in with username A
- user B logs in with username A

I want the logging in of username A by user B to invalidate the session for username A held by user A. So if people are sharing login credentials, the last person to log in kicks everyone else out who's logged in as that user.

The big problem I have is the application is deployed in a cluster across JVMs, so sessions are shared across nodes. My thought it to introduce a session listener to then inspect a table in the database which determines whether that user logged on - the part of identifying that is pretty simple as far as I can tell. The difficult part is kicking out the first user who logged in.

So, I guess my question is - can I invalidate an http session from with an MDB? If so my logic is to implement an MDB which listens on a topic and whenever a session is created that MDB checks for sessions belonging to the same user within that JVM to invalidate them (obviously skipping the JVM the login request came in on!).

Is that even possible? Is there a simpler way to do this?

Thanks,

Bic
 
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, kicking a logged-in user is kind of rude. Usually, you do the exact opposite. It's potentially even insecure, since you don't know that the evicted user was in the middle of when you do it.

Beyond that, I use the standard J2EE security system myself, so anything to do with logins is handled by whatever Realm module I have attached to the application(s) in question.
 
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
PRobably you need to record the JSessionId (or other token associated in the cookie) to indentify the different users trying to login witht he same user. THen you have to change your SSO (or your own JAAS mechanisms or any other type of Servlet listener) to invalidate the other session (probably just overwriting the current JSessionID for example) so, as the old user try to acces the page it would not have access anymore (due it jsessionj which is kind of part of the authentication process now is not present in the 'login' table any more)
 
Tim Holloway
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Luan Cestari wrote:PRobably you need to record the JSessionId (or other token associated in the cookie) to indentify the different users trying to login witht he same user. THen you have to change your SSO (or your own JAAS mechanisms or any other type of Servlet listener) to invalidate the other session (probably just overwriting the current JSessionID for example) so, as the old user try to acces the page it would not have access anymore (due it jsessionj which is kind of part of the authentication process now is not present in the 'login' table any more)



JSessionID doesn't work. All it is is a hash key to the user's session made up "randomly". So every web client is going to get a different JSessionID, regardless of userID. You can even see this in action if you attempt to connect to the same webapp from 2 different browsers on the same client computer. Each client will get a different JSessionID even if they're the same user.

In fact, when you go to SSL mode, a completely new JSessionID is assigned, even though the actual session remains unchanged. That's to prevent external attacks that could potentially access session data after secured changes had been made to it.
 
Luan Cestari
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:

Luan Cestari wrote:PRobably you need to record the JSessionId (or other token associated in the cookie) to indentify the different users trying to login witht he same user. THen you have to change your SSO (or your own JAAS mechanisms or any other type of Servlet listener) to invalidate the other session (probably just overwriting the current JSessionID for example) so, as the old user try to acces the page it would not have access anymore (due it jsessionj which is kind of part of the authentication process now is not present in the 'login' table any more)



JSessionID doesn't work. All it is is a hash key to the user's session made up "randomly". So every web client is going to get a different JSessionID, regardless of userID. You can even see this in action if you attempt to connect to the same webapp from 2 different browsers on the same client computer. Each client will get a different JSessionID even if they're the same user.

In fact, when you go to SSL mode, a completely new JSessionID is assigned, even though the actual session remains unchanged. That's to prevent external attacks that could potentially access session data after secured changes had been made to it.



Sorry Tim, I think I was not very clear. I really mean to use the cookies (which you can use it in different ways, I just cited one) as one options. The only second option that I can see is to see the IP address of the caller, but that would have many (more and different than the previous option) side effects. I can imagine some other ad-hoc solutions, but those solutions depends on the infrastructure you have there and what you expect/can deal around requirements and side effects.

So, the JSessionId would be in the cookie of that page (Browsers have to fulfill the requiments about cookies and how they work), and as the user logged have an unique JSessionId, you could record it somewhere and know which JSessionId is using the last user logged in. But this is just an sub options around the cookie as I described earlier.

You can also reach OWASP to see some recommendations around security(as this topic seems more like a security subject, which we could move it to get more people with interest about it ) : https://www.owasp.org/index.php/Top_10_2013-Top_10
 
Tim Holloway
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no session data in the cookie. The jsessionid cookie contains the sessionID, but, as I said, it's not inherently meaningful. It's just a hash key that the server uses to associate a client with a session. And its value is subject to change without notice. In particular, the old key is destroyed when the server switches to SSL and the cookie is updated with the new (sessionID) value, even though the actual HttpSession is unchanged.

Cookies are not attached to pages, incidentally. They are attached to the client program instance. Which is why a copy of IE and a copy of Chrome both running on the same computer will have different sessionIDs, even though they are both the same user. Although they will not be the same session.

If you attempt to identify me by my IP address, you'll see it's 216.199.14.19. As is every other desktop computer on the mousetech.com domain, since it's a NAT system. So, as you can see, as a user identification method, the source IP is useless.
 
Luan Cestari
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:There is no session data in the cookie. The jsessionid cookie contains the sessionID, but, as I said, it's not inherently meaningful. It's just a hash key that the server uses to associate a client with a session. And its value is subject to change without notice. In particular, the old key is destroyed when the server switches to SSL and the cookie is updated with the new (sessionID) value, even though the actual HttpSession is unchanged.

Cookies are not attached to pages, incidentally. They are attached to the client program instance. Which is why a copy of IE and a copy of Chrome both running on the same computer will have different sessionIDs, even though they are both the same user. Although they will not be the same session.

If you attempt to identify me by my IP address, you'll see it's 216.199.14.19. As is every other desktop computer on the mousetech.com domain, since it's a NAT system. So, as you can see, as a user identification method, the source IP is useless.



I'm just trying to help you =) Don't take anything like personal (IDK if you are see me replying as a 'flame war', I'm just trying to help (giving suggestions and make them more clear)).

About the Jsessions you replied, I think there is two points there, one very important from your scenario in the cookie solution point of view. As you said the the customer switch from HTTP to HTTPS in some cases, I would recommend http://stackoverflow.com/questions/4635425/tomcat-keep-session-when-moving-from-https-to-http which the answer express my opinion about it (basically, it is not good mix HTTP and HTTPs, especially for cookies).

The second point is about the cookie. You are right about the Chrome and IE thing, it is really expected. If that doesn't no fulfill the requirements, you would need to go to a more low level solution, like using activex with jaavscript to get the domain user logged or other solutions. But the main point I can tell you review the quick conversation we had so far, it's better first you specify what you mean by user in the first place and how you identify them (which attributes make an user unique, like user desktop name, IP, etc ). At this point I would say that it is a machine, which even if the user open in different browsers, the user would keep the same session. If it is really this case, you probably would need some low level api from the OS to get a more accurate identification.
 
Tim Holloway
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not offended. I'm just trying to share what I've learned over the last decade or so. And occasionally, I'll blow it because either my memory has failed (again!), something got changed and I didn't know about it, or I'm giving a "common sense" answer that turned out not to be so sensible. Which is why it's always good to have Tomcat's source code and a good debugger handy!

The StackOverflow question presented sounds, er, "questionable". On the one hand, the querent is describing what happens when the J2EE standard container security system handles logins. On the other, he talks about users going directly to the login page. Which will not work using container security, since the login page is handles by the server itself, not the web application and therefore a direct URL reference to it won't have the proper context. Which, incidentally is why he would see the sort of problem that perplexed him.

And they're right. Mixing HTTP and HTTPS URLs on the same page is asking for trouble. Plus IE gets all whiney about it. Although mixed URLs are not the primary concern for the question that this topic is about.

The definition of "user" is pretty unambiguous in the J2EE standard. A User is associated with a specific instance of HttpSession. The session resides entirely on the server and only an identifier is passed back and forth (via cookie, if enabled, or URL rewriting) to the client in order to maintain continuity (state) in what is actually a stateless protocol (HTTP/HTTPS). An authenticated user is one who furthermore has presented credentials that assure a specific identity and therefore has been associated a specific (non-null) ID with zero or more security roles. Note that unauthenticated users have no unique identifier (HttpServletRequest getRemoteUser returns null). They're simply a set of anonymous sessions. When you authenticate, the session user gets associated with an authenticated ID and set of security roles for the life of the session (or in JEE, until the new logout method is invoked). The userIDs, passwords and roles are maintained externally and verified via an appropriate Realm.

The J2EE standard says nothing about restricting the number of times a given authenticated identity can be associated with sessions concurrently. So user ID JSMITH could be 6 different people/sessions on 3 different continents. A security Realm could be designed that forbids concurrent use, however by simply checking a repository of logged-in users and rejecting authentication of the late-comers. Doing the opposite - logging off someone in favor of someone else is somewhat more difficult. Plus, like I said, it's rude and a possible security risk as well.

Definitely don't try things like ActiveVirus, er ActiveX controls. Not only am I not the only user on my IP address, I'm running Linux, and neither Linux nor the Macintosh OS support that particular vice.
 
reply
    Bookmark Topic Watch Topic
  • New Topic