This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I'm still pretty green when it comes to cookies so forgive me if I'm asking some pretty dumb questions ;)
I've got a web application that I've written in JSF 2.0 (Apache). This application extends the functionality of another web application written in JSP. I didn't write the other web application, nor do I want to modify it, save for a bit of JQuery here and there.
The problem I'm facing is that I have no way of ensuring users of my application (the one in JSF) are properly authenticated by the larger application (the one in JSP). The way I got around that was to create a quick meaningless cookie in my JQuery code.
What I would like to do for each request is pull the cookie from the client's system into my JSF application, validate it and allow access to my application. The problem is, for some reason JSF is not "seeing" the cookie. Currently my code is this:
Here are the properties of the cookie:
Send For: Any Type Of Connection
Http Only: No
Expires: <2 minutes from creation>
You shouldn't have a problem with cookies, but if all you're looking for is to determine whether a user was authenticated in the JSP part of the webapp, use the Ultimate Cookie, instead!
The "Ultimate Cookie" is the one that contains the user's sessionId, which is the hashcode that the appserver uses to find the user's HttpSession object when your code does a request.getSession(). Which is my way of saying, that if you use a session-scope object, you don't need to mess with cookie code at all, since the sessionId cookie is automatically managed without any user code.
JSF can work with session-scope objects in 2 ways:
1. If the object is defined as a JSF Managed Bean and it is first used in JSF code, you can automatically configure it and inject it into JSF code without any explicit Java code on your part.
2. If the object is created as a JSP session object, you can do a Service Locator type of operation to obtain the session via the FacesContext and use the session.getAttribute() method just like you would in ordinary servlet code.
Session objects - whether JSF-Managed or servlet-managed - are the same thing. The only difference is whether JSF constructs them or servlet code does.
I would add that using session objects instead of cookies would be a better approach from the standpoint of security, but it looks like you're working with a DIY login system, so it's very unlikely that there was a lot of security to begin with.
An IDE is no substitute for an Intelligent Developer.
Joined: May 08, 2012
So if I need to access the session scoped object for authentication (from JSF, created in JSP) I would need to share the session of both websites, correct?
I have to use Tomcat6 for my container, so I'm assuming I would be setting crossContext if this is the case.
I wanted to try and avoid doing this because I may be deploying this extension on systems where I do not have the permission to change the context settings of Tomcat.
You would be far better off implementing an industry-standard Single Signon (SSO) solution. If you did that, it would move the whole login process out of individual apps and into a central security system that would be shared by all (participating) webapps, regardless of what programming language or platform they were written in. Since that would not only give you global, common identity management, it would give you a common userId, you could then use that userId as a key to manage additional user-specific information in a shared backend database.
Joined: May 08, 2012
Yeah SSO would be sweet. But I'm limited be the existing application's crappy security model... eventually that is the direction I'd like to move to. But for now I need to carry on with the diy approach.
David Lawson wrote:Yeah SSO would be sweet. But I'm limited be the existing application's crappy security model... eventually that is the direction I'd like to move to. But for now I need to carry on with the diy approach.
And thereby you bring up another of the to 10 reasons I have on Why Do-it-Yourself Java Security is a BAD THING. DIY systems require code mods to the apps when you want to change security management. The built-in J2EE security framework works in large part by wrapping URLs with guards and by using a standard security API that's independent of the security provider (Realm) that's in use.
You actually are effectively attempting a limited version of SSO, but doing it the slow and expensive way. A way that is not only horribly expensive (and insecure) to get set up, but is also extremely expensive in terms of maintenance. As well as being a prime platform for security hole introduction when apps are maintained. I can tell that without even seeing the code or specs because I'm so creaky and antique-y that I worked with J2EE before JSPs were even invented yet (ugh!). And in all those years, every stupid bleeding blanking one of the DIY security frameworks I've encountered has been that way. I've worked with critical financial industry apps. I've worked with military apps. Security like wet cardboard.
Security isn't something "clever" people should design. The people attacking it are even cleverer and unlike most of us, attacking security is not a part-time job for many of them. Not that most of the DIY systems I've run into needed professional crackers to break. About 10-15 minutes tops by a rank amateur got through most of them. If you want real security, outsource it to security pros who have been extensively trained in security and have no other job duties to distract them. In the case of J2EE, the system that comes built into the webapp server has withstood over 10 years of daily use and never reported being broken. And if it is, you have someone else to blame rather than having to take the heat yourself.
Anyway, rants aside, you may be able to take a page from what I said earlier and use a shared backend database if your apps agree on a common userId that could be used as a key. If you're afraid of too much overhead, you might want to consider a multi-user in-memory database like Apache Derby instead of passing around security elements as cookies. Or, for really simple stuff, use a basic key/value store such as the "sleepycat" Berkely DB system, which comes standard (and extensively used) with Linux systems and is available in enhanced forms from Oracle.