Sample Grails 2.4, Spring Security & MongoDB Project

Posted by {"display_name"=>"greg", "login"=>"greg", "email"=>"greg@udon.org", "url"=>""} on December 05, 2014 · 4 mins read

Here's a sample Grails 2.4.4 app with Spring Security and MongoDB.

Initial Setup

I'm using Intellij Idea as my IDE but will provide the grails commands I'm using to setup the project

grails create-app springmongo

BuildConfig.groovy

Open BuildConfig.groovy and add the following in the dependencies section per the known issue described here with Spring Security under Grails 2.4.

compile "net.sf.ehcache:ehcache-core:2.6.9"

In the plugins section of the Config.groovy strike the hibernate plug and add the others shown here.

runtime ":hibernate4:4.3.6.1"
runtime ":database-migration:1.4.0"
compile ":spring-security-core:2.0-RC4"
compile ":spring-security-ui:1.0-RC2"
compile ":mongodb:3.0.2"

In Intellij, you'll be prompted to update the project, from the command line, you should execute:

grails refresh-dependencies

Setup Spring Security

Execute the s2-quickstart command to setup the Spring Security. Change the domain names for User and Role if you prefer.

grails s2-quickstart com.springmongo User Role

Customized Domains

The User, Role and UserRole domains were just created with the s2-quickstart command. Delete the UserRole domain since we can't do join tables with MongoDB. We'll embed the user roles in the User domain in a minute. To support MongoDB, the User and Role domains needs to add an id:

import org.bson.types.ObjectId

ObjectId id

In the User domain, I'm also going to add a few more fields:

String email
TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles")
Date dateCreated = new Date()
Date dateModified = new Date()
Set authorities

static embedded = ['authorities']

Also, remove the use getAuthorities function which is based on UserRole.

Set getAuthorities() {
   UserRole.findAllByUser(this).collect { it.role }
}

DataSource.groovy

Replace the entire contents of the DataSource.groovy file with the following. If you don't specify the databaseName, the application name will be used as the databaseName.

grails {
    mongo {
        host = "localhost"
        port = 27017
        username = ""
        password = ""
        databaseName = "foo"
    }
}

You can alternatively use a MongoDB connection string:

grails {
    mongo {
        connectionString = "mongodb://localhost/mydb"
    }
}

Config.groovy

With Grails 2.4 I want the fork debug options turned on and will set some basic Spring Security URL based mappings for now so that I can access the MongoDB dbconsole page:

grails.project.fork = [
        run: [maxMemory: 1024, minMemory: 256, debug: true, maxPerm: 256], // configure settings for the run-app JVM
        war: [maxMemory: 1024, minMemory: 256, debug: false, maxPerm: 256], // configure settings for the run-war JVM
        console: [maxMemory: 768, minMemory: 64, debug: true, maxPerm: 256]// configure settings for the Console UI JVM
]

// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.securityConfigType = "InterceptUrlMap"
grails.plugin.springsecurity.interceptUrlMap = [
        '/':                  ['permitAll'],
        '/index':             ['permitAll'],
        '/dbconsole/**':         ['permitAll'],
        '/login/**':          ['permitAll'],
        '/logout/**':         ['permitAll'],
        '/secure/**':         ['ROLE_ADMIN'],
        '/finance/**':        ['ROLE_FINANCE', 'isFullyAuthenticated()'],
]

Remove this line:

grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.tworks.teesheet.UserRole'

Add this line to the Spring Security staticRules:

'/assets/**':   ['permitAll']

I also want to add some lines to the log4j section:

info 'grails.plugin.springsecurity.web.filter.DebugFilter'
debug 'grails.app', 'com.springmongo'
warn stdout: ['grails.app.taglib', 'grails.app.resourceMappers']
info 'org.springframework.security'
error "StackTrace"

Bootstrap.groovy

....

Intellij Debug

To debug the app in Intellij, I follow mrhaki's guide to setting up Intellij Idea for Grails debugging.

References

Some of the posts that were helpful in doing this post were the GORM for Mongo reference documentation by Graeme Rocher and Burt Beckwith; this BPMGeek post from Sept 2013 based on Grails 2.2.3; this MongoDB blog post on using Grails with MongoDB. There are a couple of good articles on replacing join tables, like UserRole, with embedded docs. One conversation on stackoverflow and another post by Burt Beckwith. Burt shows an example User domain with the UserRole join table replaced by the embedded authorities field. His Github project is here.