Spring Security For Real with Grails

Spring Security is one of the basic building blocks I use pretty much every time I’m constructing a web application. It’s a very mature and incredibly powerful security framework, one of its main benefits being its versatility. There are hooks and plugs everywhere, allowing you to extend and combine basically any way you want.

Now, if you want to apply security in a Grails application you are typically pointed in the direction of the Grails Acegi Plugin, which does a rather decent job at applying basic security to your Grails application. It quickly falls short however when you need to start doing something more than the bare basics (which you pretty much always need to do); even though the plugin is based on Spring Security, far from everything in the original framework is supported in the plugin, and hooking in custom components is pretty much out of the question. In addition to this, the Acegi Plugin is haunted by a couple of pretty annoying bugs.

Bottom line: for any real-world scenario you will most likely want to fall back to the original, i.e. use the original Spring Security framework in your Grails application. Since Grails is Spring-based it shouldn’t be all that much work to set that up, right? Well basically yes, but as I set out do to it I ran into a number of problems before I got it right, so I thought I might as well line out the steps and pitfalls.

1. Download and Install the Spring Security jars

Typically, for the basic setup you should need only the spring-security-core.jar and spring-security-core-tiger.jar, but depending on your requirements you might need to include more of the Spring Security binaries. Place the jars in your lib directory of your Grails application.

2. Install Templates

Spring Security is based on an HTTP filter chain, which needs to be declared in the WEB-INF/web.xml file of the web application. This file is normally automatically generated for you by Grails, but for the event that you need more control (such as this occasion) you can have the default file generated for you to edit. The command for this is grails install-templates. This will generate a number of files, and the web.xml will be ready for editing under src/templates/war.

3. Add the Spring Security Filter Chain

There will be a number of filters defined in the web.xml file already. Add the Spring Security filter after the other filter definitions, but before the filter-mapping entries (all the filter definitions need to be placed before the filter-mapping ones, or else evil things will happen with any additional filters generated by Grails and we’ll get in trouble when we deploy in tomcat).

Now, after the other filter-mapping entries, add the filter-mapping for the Spring Security filter:

4. Spring Security Configuration

Now we’re ready to add the Spring Security configuration XML. Note that this configuration needs to be placed in grails-app/conf/spring/resources.xml. I initially tried to put it in WEB-APP/WEB-INF/applicationContext.xml but due to the Grails ApplicationContext loading magic that attempt failed spectacularly. We’ll start out with a minimal Spring Security configuration just to get things going; for more information the configuration topic I’ll refer to the reference documentation.

Another note of caution here: If there is anything incorrect in your resources.xml Grails will happily and silently ignore this and go ahead and start anyway. Therefore, whenever you start doing stuff with your own custom Spring configuration in a Grails app it is imperative to make sure to configure your logging so that Spring warning and error messages are logged properly or you’ll be completely in the dark trying to figure out what went wrong.

All done

As it turns out this wasn’t as bad as expected. You’re now all set to unleash the full power of Spring Security on your Grails application.

This Post Has 13 Comments

  1. Nice to see that it is pretty easy to fall back to Spring functionality in Grails.

    Thank you for the advise.

  2. Nice work,

    What Version of grails and spring security are you using?
    your schema location says “spring-security-2.0.4.xsd”

    Yet your link for the documentation points to 3.0.x?

    1. Right, that’s a mistake on my part. I should have pointed out that I’m using Spring Security 2.0.4 and Grails 1.1.1. I’ll update the link. Thanks.

  3. How would one extend this concept to use a UserService that would be used with the tag, authentication-provider tag, eg. ?

    1. Spring Security configuration details, e.g. how to configure DB access is out of scope of this blog post. This nothing to do with the Grails/Spring Security; the configuration for this will not differ in a Grails application from how it’s done in a typical plain Java application. Just add the proper configuration beans in the resources.xml file, as described in the Spring Security reference documentation. If you have more questions on Spring Security specific configuration you might want to ask in the Spring Support forums (forum.springframework.org).

  4. Hi –

    Thanks for the nice writeup.

    Have you also explored implementing the same basic setup, but using config.groovy instead of config.xml? Just curious if you did and there was a problem.

    thanks
    ds

  5. correction: using resources.groovy instead of resources.xml

  6. Hi!

    I’ve made almost the same modifications but I’ve created a file called applicationContext-security.xml with Spring Security beans and changed in the web.xml to add the new file in the param contextConfigLocation

    It works nice to me :)

  7. Alternatively, in your web.xml you can specify:

    contextConfigLocation

    /WEB-INF/applicationContext.xml
    /WEB-INF/applicationContext-security.xml

    and that allows you to use a typical security config xml file within grails.

  8. Have you figured out how to use the spring security 3 jsp taglibs in your grails gsp’s with this configuration? Doesn’t seem quite as easy…

  9. Error when adding config to resources.xml in Grails, it barfs on the http node with the following error. Config excerpt listed below (error):

    Line 43 in XML document from URL [file:./grails-app/conf/spring/resources.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element ‘http’. One of ‘{“http://www.springframework.org/schema/beans”:import, “http://www.springframework.org/schema/beans”:alias, “http://www.springframework.org/schema/beans”:bean, WC[##other:”http://www.springframework.org/schema/beans”]}’ is expected.

    ————————————————

  10. beans xmlns=”http://www.springframework.org/schema/beans”
    xmlns:security=”http://www.springframework.org/schema/security”
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
    xsi:schemaLocation=”http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.0.xsd

    <security:http auto-config=”true” use-expressions=”true”>

    <security:intercept-url pattern=”/admin/**” access=”isAuthenticated()” /
    >

    </security:http
    >

  11. Thanks for the nice post. One question: How to configure the logging to debug resources.xml bean error?

Leave a Reply

Close Menu