Apache Shiro tags for Facelets - Securing your JSF pages
First, a little introduction. You can skip it and go straight to the source code, if you want.
I started working with Apache Shiro when it was still called JSecurity, and I have to say that it really rocks! I tried to use Spring Security (Acegi) in some projects, but the easiness and lean approach of Shiro is unbeatable. For a quick introduction, here's a quote from the project's site:
Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
I've used it in Java and Grails projects, and recently I've even been experimenting it with Google App Engine. It fits very well in almost any Java platform project that needs security.
Shiro already works great in a JSF/Facelets project. You can use it's filters to grant and deny access to some parts of your application and to force authentication (redirect to login).
The only functionality missing is the power of it's JSP taglib, that are used to conditionally render some parts of your HTML, based on user's authorization, roles and permissions (you can learn how to use them with this simple example project). The problem is that this conditional rendering is not totally compatible with JSF's phases. Better than trying to fit a cube in a spherical hole, I decided to rewrite Shiro's JSP tags into a Facelets taglib, totally compatible with JSF.
All original tags are available as their Facelets equivalents, and I have introduced two new ones:
<shiro:hasAnyPermission> - Displays body content only if the current user has one of the specified permissions from a comma-separated list of permission strings.
<shiro:remembered> - Displays body content only if the current user has a known identity that has been obtained from 'RememberMe' services. Note that this is semantically different from the 'authenticated' tag, which is more restrictive.
I've already submitted a patch to Shiro's development team, but they're very busy at the moment packaging the new 1.1 version for release. So I decided to share the taglib on GitHub, and host the artifacts in my personal maven repository, as I need to use the tags in an on-going project.
If you want to try it in your maven project, add my repository to your pom.xml:
and add the jar dependency:
Now you can declare Shiro's namespace in your xhtml pages and use the tags like this:
That's it! Just keep in mind that as soon as this lib gets incorporated officially in Shiro, I'll stop updating it in GitHub and all future enhancements will only be available in the official version. If you want to see the tags incorporated officially into Shiro sooner than later, you can vote here: https://issues.apache.org/jira/browse/SHIRO-206
And if you have any suggestion, please leave a comment.
Enjoy ;)


Comments 16 Comments
Great writeup! Thanks for sharing. We'll do our best to try and support this in Shiro as an added support module as soon as we can.
Cheers,
Les
adding the power of Shiro to JSF will make the development of JSPs much easier for security purposes
I voted for your Task in the Apache JIRA. I'm wondering, does this also work with JSF 2.0 and the build in facletes? Because i'm already working in a JEE6 Enviroment
What am I not doing correctly?
However, I can not use the tags. In my xhtml file I added xmlns: shiro = "http://shiro.apache.org/tags" but netbeans sends me an error that says: No library found for this namespace. What I can do?
One thing to notice: please put somewhere in the article that shiro-faces taglib only works with JSF 1.2.
I have spent almost hour and a half trying to weed out strange errors until I found on some forum your post that says taglib only works with JSF 1.2 for now. (No, I don't have a habit of looking into pom files to see what the dependencies are :o)
Regards,
Nidal
@NidalP: Now it works with JSF 2 :) Anyway, thanks for noticing.