I started using Spring Security in 2007 when I was tasked with adding security to a Spring/Hibernate application at the company I was working for. There were a few options to choose from, none of them particularly friendly to work with, and we chose Acegi Security because it was the most popular option for Spring applications. My experience was like that of many others – it was confusing and frustrating, and required a ton of XML. The next major release was renamed Spring Security 2.0 and it was officially brought in as a Spring subproject, and fortunately it made configuration dramatically simpler by using Spring XML namespaces.
When I started using Grails and found that it supported plugins one of the first I looked at was the acegi plugin, and I eventually became the plugin maintainer and later wrote most of the newer Spring Security plugins. I keep working with Spring Security because it’s very powerful and because I know it well, having struggled with learning Acegi 1.0.x, and then moving on to Spring Security 2.x and 3.x.
Grails has another popular security plugin, the shiro plugin. I haven’t used it but it has the reputation that it’s easier to use than Spring Security. I think that’s less the case with the plugins since spring-security-core and its dependent plugins are quite user-friendly, but more so when you’re not using the plugins or are working directly with the underlying APIs. For the most part the feature set of Spring Security and Shiro overlap with Spring Security having a few more features (but Shiro is catching up quickly). But one feature that is strangely implemented and hard to use in Spring Security but easy to use in Shiro is ACLs and permissions.
It took me a long time to get the spring-security-acl plugin finished, in large part because the Spring Security ACL implementation is overly complicated and hard to use. It works, but it’s far from user-friendly. But looking at the Shiro plugin’s documentation I was jealous to see that you can do simple things like grant the “printer:print:*” permission to a user, and the wildcard implies the “printer:print:lp7200” and “printer:print:epsoncolor” permissions. Then you can guard a service method with
@RequiresPermissions('printer:print:*) and a user granted “printer:print:*” (or a more specific permission like “printer:print:lp7200”) can call the method, and others will be denied.
A while back I thought it would be cool to be able to use Shiro’s permission support in addition to Spring Security. I started working on it a few months ago and picked it up again this weekend and got it working. Basically it just adds a filter that runs after the Spring Security
SecurityContextPersistenceFilter which populates the
SecurityContext (typically from the HTTP session) with your current
Authentication, and creates a Shiro
Subject with the same information and registers it in the
ThreadContext. In addition it adds support for storing permission information. This is done by default with a domain class that has a many-to-one relationship with the existing user class, but this is customizable.
So now you can install the spring-security-shiro alongside the spring-security-core and any of its dependent plugins and use both approaches. You can even use Spring Security ACLs and Shiro ACLs at the same time.