Real Ultimate Programming

The Home for People Who Like to Flip Out and Write Code

Grails, the Acegi Plugin, and HTTP Basic

If you’ve heard of Rails but can’t use it for whatever reason–my reason was an incompatible legacy schema–maybe Grails will work for you. Unashamedly inspired by Rails, Grails is written in Groovy and aims to provide the convenience of Rails while adding configurability and leveraging the power of the massive number of libraries written in Java and the other JVM languages (including Ruby, thanks to projects like JRuby). Between what comes with Grails out of the box and the available plugins, it can really take a big chunk of the grunt-work out of webapp development.

One of my favorite plugins so far is the Acegi plugin. It bolts Spring Security onto your Grails project and provides for configuration using the concise Groovy DSL for Spring. Just type grails install-plugin acegi to install the plugin, and start leveraging Spring Security.

One of the nice things about Spring Security is its built-in support for HTTP Basic authentication. Just change basicProcessingFilter from false to true in your SecurityConfig.groovy file and your application will now look for user credentials in the HTTP Authorization header. The only problem is that if no Authorization is sent, the server sends a 302 Found response to send the client to a login page. To be fully compliant with the HTTP Basic spec, it should be sending a 401 Unauthorized response with details on the supported authentication mechanisms. If you’ve read the documentation for the HttpBasicProcessingFilter—which you enabled by setting basicProcessingFilter = true earlier—you might expect Grails to be using HttpBasicProcessingFilterEntryPoint, but you’d be wrong. In an effort to be user-friendly for human users, it is instead using an AuthenticationEntryPoint that sends the 302. To change to the strict HTTP Basic mechanism, you’ll need to rewire the AuthenticationEntryPoint Grails is using by adding the following to your resources.groovy file:

authenticationEntryPoint( {
    realmName = 'YOUR REALM GOES HERE'

Back to flipping out….