What's the best way to manage authorization in a custom jaas environment?
When I log the user, I put info about him in the sessionScope. What I'm doing now (And I know it's a terrible thing to do) is to perform authorization validation in the constructor of the bean, so when someone tries to go to some page, the constructor of it's associated bean gets called and the method validates if I have info about the user in sessionScope, if not it redirects to login page. This is not good because all the getters of the page are still getting called, and if it is a session bean then I have to be careful of removing it after redirection.
I think I should write this code in JSP directly into my JSPX page, but I don't know how to do it.
Well, I use container-based authentication and authorization (in fact, I'm rather rabid on the subject). So I'd configure my server for the JAAS Realm and let the server handle the login and role-checking processes. That way I don't have to worry about some clueless fool mucking up security when maintenance time comes around and I don't have to do massive rewrites to the display/business logic if the security environment changes. And I can test it without needing access to the production security system.
The only concession I have to make for JSF is that secured pages need to be navigated to via JSF <redirect/> rules, since the container determines security primarily from the user's URL, and the redirect ensures that secure functions aren't requested under insecure URLs.
An IDE is no substitute for an Intelligent Developer.
Martin Lopez Ochoteco
Joined: May 28, 2009
Hi Tim, thanks for your response. I tried container based security but it didn't suit my needs. I need an authentication and authorization service that can perform validation against an Oracle Internet Directory, with password change, password expiration messages, etc.
From my bean I'm doing this to redirect:
But I want to do it from my JSPX, so in case the user is not logged my page redirects without creating any bean or calling all the getters.
Actually, I'd bet I could still use container-based security. Authentication with a security server is not really a problem. For standard database or LDAP, the stock Tomcat Realms should manage that (if you're using Tomcat or something like JBoss with embedded Tomcat).
For a "countdown" indicator, it's a little more interesting. I'd actually probably favor a "nag" message in the page header or footer with a link to the code that connects to the security maintenance API. On the other hand, if you want to simply flash up a post-login page, that can be done with a little help from a servlet filter.
I have something like that right now. When a page request comes in, I check for a session. If there's no session, I'm not logged in. If there is a session, I check to see if I've cached the user's profile as a session object (since JSF can create sessions even when you're not logged in). If there's a UserPrincipal attached to the HttpServletRequest, that means that someone's logged in, so if I don't have a profile in the session, I fetch one, using the UserPrincipal as the key and place it in the session.
I'll admit that there are a few gaps in the functionality of the basic J2EE CBS framework, but I've found them easy to fill. But there are more gaps in general JSF itself at the moment (like bookmarkable URLs), so I haven't reallyhad to spend too much time or effort on security.
I did have to write a custom realm for my latest app, though. It authenticates against a database, but the user's requirement was for case-insensitive user ID's. Which is perfectly reasonable - just gimmick up the SQL a bit. But oddly there's no option for case-sensitivity in the standard Tomcat database realms. So I subclassed them and added a case-folding option. Less than a day's work, and I can use this realm not only for the current app, but for any other webapp with similar requirements. Including third-party webapps that use container-based security.
If this kind of stuff doesn't appeal to you though, I'd recommend that you implement your security checks in a servlet filter. The absolute worst place to put authentication detection is in the business part of the app, for reasons I've already mentioned. Using a filter can give you much the same effect as CBS - it can guard the gate against all comers and not just the expected ones. It won't give you as much portability as an externally-supplied security manager, and you won't be able to take advantage of the J2EE security methods and resources, but at least it's a lot safer than per-view security.
Martin Lopez Ochoteco
Joined: May 28, 2009
Yes, I think your first option is the best approach. I'm using Oracle Container for Java (OC4J) that is embedded in my Oracle Application Server (I think) but it's all the same I guess. I will look for the procedure to configure it right.
To manage LDAP operations, I can do it the same way, with javax.naming.directory.
Thanks, at least my doubts of what is the goal that I should go after is cleared. I will continue and see if iI can make it work.