Using MongoDB With Version 2.x of the Grails Spring Security Core Plugin
Sunday, December 01st, 2013With a few customization steps it’s easy to use MongoDB to store user and role information for the spring-security-core plugin instead of using Hibernate, and after seeing this Stack Overflow question
I thought I’d write up some notes on how to do this with the current plugins. Note that much of this is based on this blog post
.
I created a demo application using Grails 2.3.3; it’s available on GitHub. The general steps were:
$ grails create-app mongoSpringSecurity
- add the plugins to
BuildConfig.groovy
$ grails s2-quickstart auth User Role
- update
DataSource.groovy
to use MongoDB - create a custom
UserDetailsService
and register it inresources.groovy
- create a test role and a user in
BootStrap.groovy
- customize the domain classes to use MongoDB
- add tags to
index.gsp
to add a login link if you’re not logged in, and show that you’re logged in if you are
One difference between what I do here and what was done in the original blog post is that the custom UserDetailsService
is not a Grails service – it’s in src/groovy
and not in grails-app/services
. It wasn’t necessary to be a real service then and isn’t now; it’s a coincidence that the Spring Security interface name ends in “Service”. See the plugin documentation for general information about customizing this bean.
You can see the source for the custom bean here. By embedding the authorities in the user domain class, the many-to-many relationship is not needed and the model is a lot simpler, so the class implementation is also – for example there’s no need for a
withTransaction
block to avoid lazy loading exceptions.
The changes for the User
class are fairly minor. You need static mapWith = 'mongo'
if you have both the Hibernate and MongoDB plugins; in this case it’s unnecessary but harmless to leave it in. The id
field should be an ObjectId
, and I retained the other customizations from the earlier blog post (the embedded roles, the addition of the email
field, extra constraints, etc.). The Role
class changes are similar.
Since we’re using a custom UserDetailsService
, we can delete the userLookup.userDomainClassName
, userLookup.authorityJoinClassName
, and authority.className
properties from Config.groovy
, and since the roles are embedded in the user class we can delete the generated UserRole
class.
You should be able to clone the repo and start the application (assuming you have MongoDB and Grails 2.3.3 already). Click the login link on the start page and after you successfully authenticate, the link should be replaced by a message.