A question that often comes up in when looking through JSF <a target="blank" href="http://forum.java.sun.com/forum.jspa?forumID=427&start=0">forums</a> or idling on IRC is, "How do I secure my JSF app?" to which, of course, there are a myriad of options. At <a target="blank" href="http://www.iec-okc.com">IEC</a>, we use <a target="blank" href="http://www.acegisecurity.org/">Acegi Security</a>. That answers only part of the "how," though, as Acegi is not the easiest thing to learn. In this blog entry, I’ll detail how we have Acegi implemented at IEC. While it’s not perfect, it works well for us, and should be enough to get someone moving in the right direction.
The first step, of course, is to download Acegi, and integrate with the web application. Once the jars have been installed in WEB-INF/lib, web.xml needs to be edited:
I’m not Acegi expert, and I make no claims to understand what all is going on here, but I have included the whole config file as I found it difficult (at the time, at least) to find a complete example that uses the Acegi 1.x package and class names. I must also note that I’ve done my best to back out IEC-specific changes, so there may still remain same changes that need to be made to get this to work in a "clean" environment (read as: this should work, but it may not. If you have to make changes, please let me know and I’ll fix my example).
Once Acegi is setup and configured, we can start protecting resources. The configuration above protects all URIs that start with /foo, but it is also sometimes desirable to protect only certain parts of a page. Acegi ships with some JSP tags that make that possible, but these work outside the JSF lifecycle. To solve that problem, Cagatay Civici has written some JSF tags that do live inside that cycle.
Here’s an example from an app we have in poroduction. In this particular snippet, if the user has the correct permissions, we allow him to approve a request or resubmit the order:
And that’s all there is to it. Once you get it setup, it’s really not too difficult to work with.
I have seen some balk at using Acegi, given its dependence on Spring, but, while it’s true that you must have Spring in your classpath for Acegi to work, by no means does that require that the application itself be Spring-based. In fact, we’re using this very approach in an application that uses no Spring at all, but, rather, some EJB3 session beans (and Ajax on the front end). So, if you can live with the extra few jars to solve the dependencies of Acegi, it plays well JSF, even in a non-Spring app.
What are your thoughts? Do you see ways to improve this approach, or do you have a better one altogether? I’d love to hear your feedback.