I’m marching through a pretty large groovyblogs refactor, with the goal of tidying up the codebase considerably. I’ve made a move to the JSecurity plugin so I can add a “remember me” feature, which paves the way for more a more sophisticated “preferences” subsystem down the track.

The only problem was that I already has an Account table which contained passwords (base64 sha1) and a role column (string). I really wanted JSecurity to use my existing Account.password and Account.role fields when constructing it’s user subject since I didn’t want a massive migration job on my hands. There also wasn’t really a need for all those JSec* domain objects since I already had the data I needed in my Account table.

Fortunately JSecurity supports custom “Realms” - so I could plug in a new authentication substem that uses my existing table structure, but expose it all to JSecurity’s subject, principal, and role context. I just needed to supply the appropriate methods to my new Realm and I was in business. For example, since my roles were implemented as a simple String, implementing role integration with JSecurity was a matter of providing my realm with:

def hasRole(principal, roleName) {
        return Account.findByUseridAndRole(principal, roleName)
    }

As for the authentication portion, I also provided my own authenticate routine to look after the convension to base64 SHA1 since none of the standard JSecurity CredentialsMatcher implementations seemed to handle that (though in a future iteration I could probably simply extend and customise SimpleCredentialsMatcher to handle it pretty quickly). With my authenticate routine in place, there was nothing more to do but start using the JSecurity tags! First up was to a basic filter to catch the secured actions:

import org.codehaus.groovy.grails.commons.ApplicationHolder

class SecurityFilters {

    def filters = {

       accountOperations(controller: "account", action: "(index|edit|update|deleteFeed|addFeed|testFeed)") {
            before = {
                accessControl(auth: false) {
                    role("user") | role("admin")
                }
            }
        }

    }
}

All the role tags just work out of the box, since the Realm does all the heavy lifting of converting my role strings to JSecurity Role objects. The only thing that proved tricky is getting the “remember me” stuff happening for cookie authentication.

JSecurity treats users who authenticated “directly” as a different story to those who authenticated via a “remember me” cookie. If you want your filters to handle either, you’ll have to set that “auth: false” property on the accessControl check as shown above.

The last piece of the puzzle is implenting the tags for conditional display of the appropriate tab. In order for things to work for both remembered and directly authenticated user, I needed to user jsec:user and it’s mate jsec:notUser:

Alrightly, with security knocked over, it’s on to some “endless page” action for the home page ala DZone. I’m thinking of having a look at the jQuery endless page plugin to see if it fits the bill. Good chance to get up to speed on jQuery at the same time. Seems to be all the rage these days.

With the last few chapters of Grails In Action still in final copy edits, I’m totally exhausted and ready for some R&R. I’m off to the beach with the fam for some well deserved web-and-cell-free holiday action! Hope you guys have a great Easter!