• Post Reply Bookmark Topic Watch Topic
  • New Topic

custom security and HttpSession access

 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I think I have a question for someone with alot more knowledge of JSF than me. I'm creating an app with custom security and I want to make sure that there will only be one session per account at a time (or one session per account if it's an privileged account of some sort). I was thinking of scanning a list of users already logged in (held in an application-scoped bean) and then denying access if the account is already logged in - BUT it is very simple for someone to lock themselves out for 30 mins that way!

Suppose they finish using the site and instead of following the 'Log out' link they just close the browser. The session is still running and if they decide 5 mins later they need to do something else, they will try to log on and be denied as that account is already logged on and will be for 25 mins until the session times out. My solution to this is to 'force' users into more appropriate use of their accounts by 'bumping' the currently logged in person off by invalidating their session if another person tries to log in with the same account. I like this idea, as it will (I hope) stop people from using eachother's accounts.

The problem, however, is invalidating the existing HttpSessions. How can I know which is the right one and how can I access it? My plan is to use a HttpSessionListener that will add the session to an attribute of the ServletContext (which as I understand would mean it would then be application scope) when the session is created. When a user attempt to log in I would want to access this list and check each session's UserBean for the same account, and if found, invalidate the session

I really want to have the session information and id's of currently logged in users in an application scope managed bean. Can I instantiate it in my listener if it doesn't exist yet? How does this relate to declaring it in faces-config.xml? Can I even access it? If I manually invalidate the session will the listener's sessionDestroyed() method still run? I was thinking of removing the session object from the application-scoped variable in the sessionDestroyed() method - would that work or would it get tied up somehow?

Is my idea rubbish and will it not work? Is it really bad programming practice? I'm not too hot on J2EE design principles. I would really appreciate any and all information the more experienced forum members could offer!
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My idea of storing the sessions seems to work in some simple test cases. I was able to start a few sessions, add them to the application bean manually (clicking a button), and then kill all sessions except the current one when you click another button.

Someone told me that I will have problems storing the HttpSession object in my application scope bean because it's not Serializable and that my code wouldn't even work if I wasn't using Tomcat. Can anyone verify this?
 
Tim Holloway
Bartender
Posts: 18408
58
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HttpSession is an interface, and interfaces are not serializable. Same problem with JDBC Connections.

Even using Tomcat, you can run into problems. If you are clustering, the Session data is serialized from one JVM in the cluster to another, but no guarantees apply to the internal parts of the session.

It is safe to keep stuff in objects that implement java.io.Serializable that themselves are stored in the Session.
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the info, I'm not sure I understand it though... I don't know what clustering means in this context - so I'm pretty sure I'm not doing it

My sessions are stored in the application-scope bean and removed when the user logs out or is 'bumped off'. I have a crude working example of this already working, and I haven't had any problems yet. If I'm not clustering do you think I'll be ok? I need to be able to support about 20 sessions at a time, maybe more.
 
Tim Holloway
Bartender
Posts: 18408
58
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Clustering means having multiple Tomcats running in a configuration where your session is effectively established with all the tomcats (the cluster), instead of just one of them. Which means that if one of the tomcats goes down, another one will pick up the work and continue instead of having the user get logged off and losing whatever they were doing. Even if you never expect to actually do clustering, however, it's good practice to design cluster-friendly apps, since they're more closely conformant to the spirit of the J2EE specs and you never know when you might develop something so wildly successful that clustering becomes important.

Personally, I prefer container-based security where possible, since it's more comprehensive and someone else had to do all the dirty work designing and debugging. Also it's pretty much immune to being bypassed by people using "magic" URLs that do an end-run around login services.

However, tracking online users isn't something CBS was designed for. If I had such a need in a CBS environment, I'd probably arrange for a service that the session-create event handler could post to and that the session-destruction event (e.g. logout/timeout) would deregister from.

But in any event, I just wouldn't recommend trying to serialize/deserialize the actual Tomcat HttpSession objects, since there might be important bits than only Tomcat knows about and thus, you wouldn't be preserving everything properly. That's because an interface describes some of the properties of the class that implements it, but not necessarily all of them.
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the info Tim.

I would like to use CBS because it seems alot simpler, but as far as I can see it won't allow me the level of control I can get with a custom solution. The requirements for this project include the ability to very, *very* finely tune what people can and can't do.

When you say you "wouldn't recommend trying to serialize/deserialize the actual Tomcat HttpSession objects", are you suggesting that I just shouldn't go with my application-scope bean storage idea at all (we won't be using clustering for this app)? It really seems to be the answer to my problems - do you have a better idea for how I can achieve the same result?
 
Ram Gokul
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am also a newbie in J2EE but I have been designing stuff for some time . So let me give a try. We can use a combination of DB-J2EE approach to your solution.

First , the number of concurrent user sessions per User must be addressed in the Database tier.( It will be dependent on the Admin / Users previlige).
Upon User loggin , make a DB call ,to find out whether this User has logged on and take appropriate action. For example , if the User has already logged on and if he is allowed only 1 login , then we can deny him.


As far as the session management is concerned , have a reasonable <session-timeout>5<session-timeout> . So, if a logged in user , has left for lunch or closed the browser , then session timeout will occur in 5 minutes and sessionDestroyed method of SessionListener will fire , where in you can make a DB-Call to update table back to 0 for this user .

Next time he can log in and there will be no problem.

My advce will be to post this in design pattern as there are lot of Java Gurus around there . You problem is design centric and once you know what to do , yo can move it to JSF for fine tuning.
 
Ram Gokul
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am also a newbie in J2EE but I have been designing stuff for some time . So let me give a try. We can use a combination of DB-J2EE approach to your solution.

First , the number of concurrent user sessions per User must be addressed in the Database tier.( It will be dependent on the Admin / Users previlige).
Upon User loggin , make a DB call ,to find out whether this User has logged on and take appropriate action. For example , if the User has already logged on and if he is allowed only 1 login , then we can deny him.


As far as the session management is concerned , have a reasonable <session-timeout>5<session-timeout> . So, if a logged in user , has left for lunch or closed the browser , then session timeout will occur in 5 minutes and sessionDestroyed method of SessionListener will fire , where in you can make a DB-Call to update table back to 0 for this user .

Next time he can log in and there will be no problem.

My advce will be to post this in design pattern as there are lot of Java Gurus around there . You problem is design centric and once you know what to do , yo can move it to JSF for fine tuning.
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Ram, those are interesting ideas and I have considered the DB idea before but my users need longer sessions and I want to 'bump off' the currently logged in person when another person logs in with the same id (partly a deterent to using eachother's accounts!). The only way I can think of this is with my current solution to keep track of the session and then invalidate it.

Can you tell me if I will have any problems with this under Tomcat, without using clustering? Can you suggest any precautions I should take for any problems?
 
Tim Holloway
Bartender
Posts: 18408
58
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not ignoring you, BTW. Just decided to print out your problem so I could understand it better and haven't had time to read the details yet.
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Haha, no worries, thanks Tim
[ August 03, 2006: Message edited by: Jamie Williams ]
 
Tim Holloway
Bartender
Posts: 18408
58
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm baaack! ;)

There's a problem with your basic idea of the latest person to sign on causing the previous user to be forced off. For one, work-in-progress may be lost, but that's the price of wandering away from the machine. More importantly, certain evil-minded people would use that feature to kick each other off just for the fun of it. School labs are especially prone to that kind of fun and games.

In a business setting, however, the mere idea of shared accounts tends to set auditors off. BTW, when you say a second user comes in behind the first one, I'm taking it as meaning the same account but some other terminal, since I can't actually think of a situation where the system would know if a different user simply started working with the same machine.

On the more technical side, Role-based Access Control does have its limits. I expect someday that I'm going to end up in a situation where a finer degree of restrictions will apply, and my suspicion is that the first thing I'll try will be augmenting RBAC on the coarser levels with some sort of JAAS setup.

I also expect that when that day happens, what I'll do is design a security service that the user connects to. Then I'd store the service handle (object reference returned at signon) in my HttpSession, use it as needed for security queries, and use it to sign off when the session object destroy callback is invoked.

Where I work right now, however, I may go one better. We have a custom security realm that I wrote. It provides the Java EE standard security features, but I've got the security Principal object tied to our in-house security service, and it's a fine-grained system itself. So I can provide an API that returns the fine-grain control point straight from the Principal and don't even need to store anything in the session.
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Most of what you implemented sounds much more advanced than anything I can produce right now, I've only been working with JSF & J2EE for a few months and haven't had time to look into design principles or whatever. Everything here is very rushed. I wanted a week to do memory profiling and to fix some things up before I expanded on the application, but I was told there was no time

The flaw you fnd with the basic idea is something I specifically want. This is a business setting dealing with important data and I don't want people to use eachother's accounts - yes, I am talking about a second person logging in from another terminal at the same time. They are not supposed to be shared, our clients should ask us for another account if they want someone else to be able to use the system at the same time. It might sound like an odd way of dealing with the issue, but it also solves the problem of getting rid of sessions for the same account where people have just closed their browser without logging out, then open another browser 5 mins later and try to log in again.

So... I 'm pretty much set on this idea but I need to know, will I really run into problems with storing the HttpSessions, considering that I won't be clustering?
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Serialization of sessions happens in just two circumstances: clustering, and stopping/restarting of the web application or web server. The former has no bearing on what you do (since there is no clustering), and whether the latter matters is a design/architecture issue.

In a production setting, the web app/server only gets restarted if there was a downtime for some reason. Is it important that sessions survive this downtime? In my experience it usually isn't, because users can just re-login and resume their work, since nothing of long-term significance is stored in sessions. Your application may be different in this regard, though (although I would recommend against using sessions to store important data that can't be recreated easily).
 
Jamie Williams
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for that Ulf, I understand now what the problems would be.

You are right, for my application the sessions don't need to survive a server restart, and the users can easily login again. I won't be using clustering at all, so I should be fine.

Thanks to all for their help with this issue!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!