What is Shiro?
Apache Shiro is an open source Java security framework which makes authentication, authorization and cryptography very easy to use with a simple and small configuration. It is very portable because of its independence from the used application frameworks and covers all kinds of scenarios from console over desktop client to web applications.
I searched for a security solution (authorization and authentication) which I plan to reuse in multiple “pet projects” without having to think about the same problem over and over again. My actual project is a web project based on Java EE 7 and has at the moment a JSF/Primefaces frontend. I plan to extend the application with a REST interface and an alternative UI technology for personal testing/learning and research purposes. Maybe there will also be an iOS app later on which should use the then existent REST endpoint. With that in mind I need a flexible framework to support securing JAX-RS endpoints as well as my actual JSF UI.
I previously had some experience with the Java EE standard solution JAAS as well as the JBoss project Picketlink. Additional to that I’ve worked in projects using Spring Security (but had not much to do with it) which seems to be the industry standard nowadays but besides that I did a little research about possible alternatives I wasn’t aware of and came up with Apache Shiro and Keycloak.
This four/five tools and frameworks were the solutions I considered and researched which would be the best fit for me.
JAAS is an acronym for Java Authentication and Authorization Services. It comes for free with the JDK and brings a basic set of security primitives. As it is part of the standard the Java EE containers like WildFly provide their own JAAS modules out of the box to bring container managed authentication to the table. This seems like a good idea at first but has the problem that every container vendor has its own solution which all use JAAS in the background but are often not portable.
As JAAS is just a basic set it lacks some things like convenient functions for password hashing and salting, a builtin “Remember Me” functionality or a permission system. Convenient things like providing login error messages at the login page aren’t possible out of the box either.
There are workarounds for most of this but you might get the idea that it is not very convenient to use and in the case of (security) frameworks that I use I don’t want to engineer all by myself I just want to built my applications UI and business logic while all the standard infrastructure problems should be taken care of by the frameworks I chose especially when I don’t have any special use cases and want just a simple standard solution.
2. Picketlink (and Keycloak):
Picketlink is a project by JBoss (RedHat) which solves many of the insufficiencies of JAAS . Therefore I used it in a Vaadin application a couple of years ago but unfortunately the project is cancelled for the sake of its successor Keycloak. Keycloak is basically an authentication server which is deployed as a war on its own WildFly application server. This seems to be a very nice and convenient solution which should work fine in most cases and brings all the functionality that I would have needed in my actual scenario and much more but nevertheless it is no option for me because deploying an extra WildFly container just for the sake of authentication and authorization seems overkill for me and would need just more resources from my VServer which I’m not willing to provide at this moment. Additional it would be just another Server which you have to configure, operate and update which is reasonable effort for many projects but not what I was looking for.
If you think Keycloak might be the right solution for you I recommend the blog of Niko Köbler as a starting point he wrote some nice articles and has some video recordings from talks he held about the topic there.
3. Spring Security:
Spring Security should bring everything I want and much more out of the box but here the problems begin. Spring Security seems overly complex as it can do nearly everything. On the other hand there seem to be some problems from time to time with the Java EE integration which seem solvable but from what I found in my research the usage is not that straight forward and I’m not quite sure that it works with a combination of CDI, EJB and JSF at all. As my main focus until today was more towards Java EE then to Spring I didn’t wanted to change the platform just for my little pet project so despite being todays industry standard Spring Security was out for the moment.
4. Apache Shiro:
Shiro is formerly known as JSecurity and was launched in 2004. It is a very lightweight framework with a straight focus which brings many convenience features out of the box. It is container independent and can be used with non web Java applications as well as in Java EE and in Spring contexts. This fact alone makes it very attractive to me as I could reuse my knowledge in future projects which could be on another platform than Java EE or just another container vendor. With being 12 years old it has proven to be solid and is still under active development and has a responding community if any questions, bugs or problems raise up. The JSF support could be a bit more convenient but it works just fine with reasonable effort.
At this point the choice for me was set that I wanted to try Apache Shiro as it seemed to be the best fit with my current and possible future demands. Considering the platform and framework independence together with the very simple API and configuration approach it seemed worth to give it a try as it would be easily reusable for future projects no matter if they will be on different servers or just desktop clients. With having only that very simple API it shouldn’t take much effort to get it to work and therefore even if it would not have been the right choice there shouldn’t be much time wasted in trying to make it work.
In the next article I will show an example on how to secure a basic JSF/Primefaces application as simple as possible with Apache Shiro which provides the possibility to enforce login via username/password, logout and redirect to a logout page and activating Shiros session management to provide the “remember me” functionality. The application runs on a WildFly 10.1 and uses a Java EE 7 backend. It is similar to the original prototype I used to evaluate if it could fit my needs.