[1/25] Acegi: Secure your grails application with no pain

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.5.1
Plugin Docs: http://grails.org/plugin/acegi
Tutorial resources: Download here

Tutorial topics

  1. Overview
  2. Download and install
  3. Domain classes
  4. Permissions Management
  5. Storing permissions outside the database
  6. User self registration
  7. Taglib and service
  8. Acegi events
  9. Conclusion

I have to thank a lot Rob James that helped me a lot in correcting some english issues and clarifying some things in my head. Specially in the Roles/Authentication part, witch was rewrited by him.


The Acegi Security plugin provides an easy way to work with Spring Sercurity. I really like this plugin ’cause after it is installed, it is ready to be used. Offering user authentication, registration and management out-of-the box. I’m using this plugin in some of my projects and for what I need, it’s awesome. Here are some of the features I really like in it:

  • User management
  • Online permissions (roles x uri) management when storing in a database (you can also store this in the config file)
  • A simple registration screen, protected with a simple captcha and support for mailing user’s their credentials
  • Login/logout with no pain
  • Quick OpenID and LDAP integration
  • User-chosen domain class names
  • Simple taglib and service class for integration your application


Download and install

To install the Acegi Security plugin, we’ll create a simple app called “tutorials” in witch I’ll start the plugin tutorials.

grails create-app tutorials

As any other plugin, we can choose from a remote install where the files will be fetched from the official grails plugins repository (http://plugins.grails.org) or from a local install, where you can install from a local zip file. I’ll demonstrate both.

Remote install

grails install-plugin acegi

The main advantage on getting it from the remote repository is that you’ll always get the latest plugin version.

Local install

grails install-plugin /Users/lucastex/grails/plugins/acegi/grails-acegi-0.5.1.zip

I like installing the plugins from my local repository because I’m not online all the time, sometimes I’m behind a nasty proxy and this way I can have previous versions of the plugin in case I need to get to them. Since plugin zip files are really tiny, I recommend you storing it in some old usb flash memory or in any webdav drive over the cloud… :)

After installing it, you’ll get all dependencies you need for using the plugin features (except for the mail.jar and activation.jar that will be downloaded only when needed).

The process is shown here:


Domain Classes

Authentication and Authorization firstly involves understanding some important concepts.

Who can do what?

A “User” in Acegi is a login, which represents an individual person. This User will log into your application, and will consequently have certain functions that they can perform. With Acegi, you are firstly permitting users access to your application (Authentication) and secondly determining if they can perform a certain function (Authorization).

If we were to try and map this to the physical world, you could draw an analogy with how people work in an organisation. In your company, people are “Authenticated” to get into the building with an Identification card. It confirms that the person is who they claim to be. With Acegi, we generally do this with a Username and Password (although this the main way to authenticate in Acegi, there are actual many different ways of doing this).

Once in the building, they may be “Authorized” to do certain things. These authorizations prevent the Mailroom Clerk from signing off on a $1 billion project that the CEO must do. And therefore the Mailroom Clerk may be “authorized” to do or access less things than the CEO is.

In Acegi, we do this by assigning users to certain “Roles”. Roles can be confusing at times, because they are actually quite flexible. In its simplest form, you can create Roles that represent real world Roles, such as Admin, Developer, Clerk, Manager. Then in your application, you can test if the Authorized user has that role before allowing them to perform a certain function.

A more powerful model is to break down the “functions” they can perform as roles. This will allow for more flexibility in the long term. For example, all your users may have basic access to information, but only Admins, Managers and Developers have access to Documents, and Managers and Admins can modify this information, and finally Admins will be the only role that can create users. So you can create Roles in Acegi like, “PROJECT_ACCESS”, “USER_ACCESS”, “USER_WRITE” etc.

The power in doing this, is that you can have users (individuals) sharing responsibilities without changing a line of code. So you can decide that Developers can now modify documents, and just assign them that Role.

The process of “Assigning” Roles (the Authorities) to Users (the Authentication) is done through the RequestMap entity (default by the AcegiSerurity).

With these fresh concepts, we can now create these entities inside our application using one command the plugin installed for us, the “create-auth-class” command. The command itself creates all the 3 classes we need, but we’ll pass the names of the Domain objects we want each class to have as arguments. The regular usage for it is:

grails create-auth-domains <person class name> <authority class name> <request map class name>

And our command consists of:

grails create-auth-domains User Role RequestMap

After this, we get some new files in the project:

Login user domain class: User
Authority domain class: Role
Requestmap domain class: RequestMap
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/User.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/Role.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/RequestMap.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/conf/SecurityConfig.groovy
copying login.gsp and Login/Logout Controller example.
[mkdir] Created dir: /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/controllers
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/controllers

If we run the application, we’ll notice that we have one logincontroller and one logoutcontroller, they are ready to be used and all we have to do is setup one user in the database. Due to the laziness that is consuming me right now, to create and manage the users, we’ll run the second command the plugin gives us.

grails generate-manager

After running it, we’ll have more controllers (that manage the users, roles and requestmaps) and all the necessary views.
Using the new controllers, we’ll add two new roles, one admin user (god) and one other user with simple user privileges (slave).

That’s it, you can now use the login and logout controller to test the process!


Permissions Management

Keep in mind that securing URLs is not easy. You have to think what actions are linked with what “flows” in your web app and draw from the permission graphs, linking profiles (roles) with actions. Be calm, after the first one, you’ll be the master of roles.
You’ll use the RequestMapController to do this. Access this screen by clicking on the RequestMapController link and take a look at your options. In the field labeled as “URL”, you’ll enter the URL you want to secure, and below it, you’ll enter the roles you want to grant access to it, for example, in our app, we’ll restrict the user creation process, so only admin users logged should create users.

URL: /user/create

Doing this, only admins will have access to create new users in the app.

And we’ll let any logged in user list users, but non-logged users won’t do this:

URL: /user/list

Take a look in this quick presentation, showing the users trying to log and execute the actions. Note that the “safari” user will be the admin user, and the “firefox” user will be the regular user. And note that the rest of actions/controllers (RoleController, RequestMapController) are not affected.


That’s it! As this tutorial is using the in-memory database grails offer us, let’s edit our BootStrap.groovy file so we can load some sample data (so that we don’t have to manually keep doing this). Note that I’ll secure other actions here as well.

Adding Roles:

//Adding Roles
def roleAdmin = new Role(authority:'ROLE_ADMIN', description:'App admin').save()
def roleUser  = new Role(authority:'ROLE_USER', description:'App user').save()

Adding Users:


Adding Permissions:

//Adding Users
def userGod = new User( username:'god',
userRealName:'god almighty',
enabled: true,
emailShow: true,
email: 'god@grailsapp.com',
passwd: authenticateService.encodePassword('god')).save()

def userSlave = new User(username:'slave',
userRealName:'poor slave',
enabled: true,
emailShow: true,
email: 'slave@grailsapp.com',
passwd: authenticateService.encodePassword('slave')).save()

Final Bootstrap.groovy:

class BootStrap {

def authenticateService

def init = { servletContext ->

//Adding Roles
def roleAdmin = new Role(authority:'ROLE_ADMIN', description:'App admin').save()
def roleUser  = new Role(authority:'ROLE_USER', description:'App user').save()

//Adding Users
def userGod = new User(username:'god',
userRealName:'god almighty',
enabled: true,
emailShow: true,
email: 'god@grailsapp.com',
passwd: authenticateService.encodePassword('god')).save()

def userSlave = new User(    username:'slave',
userRealName:'poor slave',
enabled: true,
emailShow: true,
email: 'slave@grailsapp.com',
passwd: authenticateService.encodePassword('slave')).save()

def secureUserEdit = new RequestMap(url: '/user/edit', configAttribute:'ROLE_ADMIN').save()
def secureUserSave = new RequestMap(url: '/user/save', configAttribute:'ROLE_ADMIN').save()
def secureUserCreate = new RequestMap(url: '/user/create', configAttribute:'ROLE_ADMIN').save()

def secureUserList = new RequestMap(url: '/user/list', configAttribute:'ROLE_ADMIN, ROLE_USER').save()

//Note that here we associate users with their respective roles

def destroy = {

Storing permissions outside the database

Depending on your application needs, it may be better to store all permissions (requestmaps) outside the database. It’s up to you.


* Pros: You can change permissions on the fly! new permissions to old roles can be assigned in the RequestMap Domain we’ve created and after its added, it s working without a restart of the application.
* Cons: All requests will have to search for the requestmap permissions inside its objects. Upgrading these objects to memory will cost in database round trips, but won’t be terrible.


* Pros: It’s faster! If your site relies on performance and you don’t expect dynamically having to secure new URLs at runtime, this is for you :P
* Cons: You will have to restart your applications when the permissions changes.

If permissions don’t change often, I strongly recommend you store all permissions outside the database, but remember.. It’s up to you and what your application needs! :)

Let’s take our tutorials app and change the permissions mapping to the static method. First of all, I’ll comment the lines on our BootStrap to not insert the permissions we did, and then, open the tutorials/grails-app/conf/SecurityConfig.groovy file. We’ll see:

security {

// see DefaultSecurityConfig.groovy for all settable/overridable properties

active = true

loginUserDomainClass = "User"
authorityDomainClass = "Role"
requestMapClass = "RequestMap"

Three important points:

* Note that our domain class names are written there, so please DO NOT change this. This will mess up with your application :P
* The DefaultSecurityConfig.groovy defines everything in Acegi’s behavior, so take a look in this file, it’s important to understand what can be done! :P
* Read this doc where all is explained about what you’ll find inside the DefaultSecurityConfig.groovy

Now, we’ll add the same permissions we’ve added before using the BootStrap, but this time in the DefaultSecurityConfig.groovy file. In a string called requestMapString, set the variable useRequestMapDomainClass to false, so the application will not use the domain class we’ve created. Pay attention to the simple syntax, using URL=ROLE1,ROLE2,….

All these changes result in this SecurityConfig.groovy

security {

// see DefaultSecurityConfig.groovy for all settable/overridable properties

active = true

loginUserDomainClass = "User"
authorityDomainClass = "Role"
requestMapClass = "RequestMap"

useRequestMapDomainClass = false

requestMapString = """

User self registration

The acegi plugin also gives us another command-line tool, that auto-generate a simple registration screen that you can use for visitors to register themselves in your app. It’s a simple form, with password confirmation and even a simple captcha! I’m using it in my own project and it works great. To generate this, all you have to do is run this command line inside your grails application:

grails generate-registration

Now run your application using the run-app command and you’ll see all the existing controllers as well as a brand new one, called RegisterController. This handle’s the user registration.

You can also send confirmation e-mails to users. But I won’t cover this on this tutorial. I’ll leave this to the Mail Plugin.

Important trick: It’s not correct to any user in your application to not have any roles, so you have to define one “DEFAULT ROLE” for self registrations. You can do this in the SecurityConfig.groovy, like this:

security.defaultRole = "USER_ROLE"

Taglib and service

Ok, I have a secured application, user can register and the roles are defined, but how will I integrate my existing application with all this new stuff? The Acegi Security plugin also installs two interesting resources in your application:


This service can be injected inside your application, such as your controllers and services. It provides access to the logged in user information that may be needed when, for example, your application need to log which user is logged in and posting articles!

You can inject the service like any other service you’ve created, and you may retrieve information about the user (IMO, the most important is explained here).
Logged in User’s principal: calling the method “principal()” on the service, will return you the Principal object that can give you the username and the authorities of the user.
I’ll show a simple snippet of an action using it:

def authenticateService

def debugPrincipal = {
def userPrincipal = authenticateService.principal()
println userPrincipal.getUsername() //shows the current logged user username
println userPrincipal.getAuthorities() //shows the current logged user authorities
redirect action: list, params: params

Just REMEMBER; If no one is logged in, the method will return the String “anonymousUser”. Be careful when trying to get the username from this String, you will get an exception.


This is the taglib that you’ll use on your GSPs to interact with the plugin.

* isLoggedIn – restrict access to content within this tag to logged in users only
* isNotLoggedIn – restrict access to content within this tag to non-logged in users only
* loggedInUserInfo -this will give you information about the logged in user domain class, you pass the property name and it returns it’s value.
* ifAllGranted – restrict access to content within this tag only if the logged user have ALL THE ROLES passed to the taglib
* ifAnyGranted – restrict access to content within this tag only the logged in user has ANY of the ROLES that was passed to the taglib.
* ifNonGranted – (I think you got it!) Only will show the content if the user DOES NOT have any of these roles

Only logged users (no matter witch roles) will see this text. This is useful to build the "Welcome ..." text and the logout link!

Only anonymous users will see this. This is nice to build your "login" or "registration" link!

<!-- Let's pretend we are logged as our 'god' user -->
<g:loggedInUserInfo field="username"/> <!-- will show 'god' -->
<g:loggedInUserInfo field="email"/> <!-- will show 'god@grailsapp.com' -->
<g:loggedInUserInfo field="userRealName"/> <!-- will show 'god almighty' -->

<g:ifAllGranted role="ROLE_ADMIN,ROLE_USER">
This information will be available for admins whom have the ROLE_USER associated either.

<g:ifAnyGranted role="ROLE_ADMIN,ROLE_USER">
This information will be available for any logged admin or user.

<g:ifNotGranted role="ROLE_ADMIN">
All sessions that have the ROLE_ADMIN associated will not see this message!

Acegi events

Let’s imagine you need to log every successful or unsuccessful user login in your system, or any other event that Acegi listens to. This can be done by building your own listener class that implements the ApplicationListener class. Implementing this interface will force you to define the onApplicationEvent method that will receive an ApplicationEvent instance.

Remember swing onClicks button events? This works in a similar way, you’ll have to check the class of the event using the “instanceof” and choose what events you’ll log, and what you won’t.

Here’s an example, logging any user login on our application, we’ll define this simple class:

import org.springframework.context.*
import org.springframework.security.event.authentication.*
import org.springframework.security.event.authorization.AbstractAuthorizationEvent

class AcegiEventListener implements ApplicationListener {

void onApplicationEvent(final ApplicationEvent e) {

if (e instanceof AbstractAuthenticationEvent) {

if (e instanceof AuthenticationSuccessEvent) {

println "** Attention: User ${e.source.principal.username} is logged!"

After this, we still have to register our class in the spring beans groovy file, so the application can find it (IMO, this should happen automatically with files ending in “ApplicationListener” as it happens with filters :P what do you think?).

beans = {

acegiEventListener(AcegiEventListener) {}



That’s it folks, a simple tutorial that shows how bad our world would be if we had to implement all this by ourselves. I love grails plugins and think without it all, grails development would be horible.

Acegi is one of the most complete plugins we have, and I really like it. This tutorial is much longer than I planned (and the others that will come), but I removed too much stuff I didn’t have time to write. Maybe I’ll do it other posts.

Thank you for reading this, and please spread it out!

Next tutorial will be about the Searchable Plugin

Want to be informed on blog news? Sign up for our feed and follow me on twitter!

36 Comments so far

  1. Ben Tate on March 19th, 2009

    Hi, when i got through the step:

    grails create-auth-domains User Role RequestMap

    I get errors in my LoginController:

    import org.codehaus.groovy.grails.plugins.springsecurity.RedirectUtils
    – cannot resolve symbol ‘springsecurity’

    import org.grails.plugins.springsecurity.service.AuthenticateService
    – cannot resolve symbol ‘grails’

    import org.springframework.security.AuthenticationTrustResolverImpl
    – cannot resolve symbol ‘security’

    I’m using Grails 1.1, Groovy 1.6, and Intellij IDE

    Is there some other library I need to import other than installing the acegi plugin using the given:
    ‘grails install-plugin acegi’ command?

  2. lucastex on March 19th, 2009


    That’s strage, cause as you saw in the first screencast, I just created the app and installed the plugin, nothing more than this.

    Have you tried doing this outside the IDE, just like the screencast?


  3. Ben Tate on March 19th, 2009

    I tried it outside the IDE and it worked as advertised. Must be an IDE problem — maybe the way it handles grails plugins since the change in 1.1 maybe?


  4. lucastex on March 19th, 2009


    Probably, since grails 1.1 changes the way it handle plugins. They are not stored inside the project folder anymore.

    So, that’s it! :P

  5. Ben Tate on March 20th, 2009

    That makes sense. Thanks again for making this tutorial available, it was very helpful! The videos were especially great.

  6. lucastex on March 20th, 2009


    Thanks. Come back next week and check the Searchable tutorial. :)

  7. Hiroshi on March 20th, 2009

    I have problem with generate-registration. It doesn’t work how you descibed. Seems it has to do that by generate-registration the plugin tries to download some mail-1.4.jar. But I’m getting a conntection time out Exception.
    I’m behind a proxy, but install-plugin normally works because of a proxyConfig in my profile.
    1. Seems that the Acegi plugin doesn’t read the proxyConfig?
    2. Why mail-1.5? The normal mail plugin is 0.5, but installing this doesnt help? Is it another mail plugin?
    3. How can I get around it? Is there another proxy config within the Acegi Plugin?
    Thank you for your great work.

  8. Raphael on March 20th, 2009

    Great tutorial. Very didactic. I’m eager for the Axis2 one.


  9. Sobre Grails | Dev2Dev Brasil on March 20th, 2009

    [...] do Lucastex está montando uma série de 25 tutoriais para desenvolvedores Grails, o primeiro sobre Acegi: Secure your grails application with no pain já  esta no ar, nas próximas semanas os próximos estarão disponíveis. Rating 3.00 out of 5 [...]

  10. Larry on March 20th, 2009

    I had the import issue with both grails 1.0.3 and 1.0.4, so it isn’t something new. I worked around it by using standard spring style instead of controller annotations. Its documented on various blogs/forums and still exists as far as i know.

  11. lucastex on March 20th, 2009


    The generate-registration command explicity needs to download the mail.jar and activation.jar to let this works. This is because it provides an option to send an e-mail to user after its registration. Try running this command outside this proxy.


  12. lucastex on March 20th, 2009


    Hey brazuca :D
    Thanks for visiting!

  13. Antoine on March 21st, 2009

    Thank you for this great tutorial. Acegi plugin is impressive and this article helps really to understand how it works. Great job !

  14. Pedro Herrera on March 22nd, 2009

    Great Job !!! I have a question about ACEGI, How do I change the text messages to another language(Portuguese, for example).

    Thanks a lot.


  15. lucastex on March 23rd, 2009

    @Pedro Herrera

    Thanks Pedro! Acegi’s messages are hardcoded inside its controllers. To change your messages, you’ll have to inject the ‘messageSource’ in your controller and create your own messages.

    This would be a nice patch to Acegi, :)

  16. alex on March 25th, 2009


    thanxs for your tutorial. is there a smart way to solve problems like:
    only user x ist allowed to edit/delete his own blogposts, or only user x is allowed to view his own offline blogposts. (eg. user has role “OWNER” or “CREATOR” to a set of instances and therefore a resulting list of authorities eg. MAY_EDIT, MAY_DELETE and so on…

  17. lucastex on March 25th, 2009


    All users are OWNERs and CREATORs. You can check his authority using an interceptor in the edit action. Before editing, check if he is owner of the post.


  18. alex on March 26th, 2009

    I’m not sure I understand what you mean, can you please give me an example

  19. Dennis Carroll on March 27th, 2009


    I saw the same issue. Just give the Java VM your proxy server and port info. For example:

    grails -Dhttp.proxyHost=myproxyserver.com -Dhttp.proxyPort=80 generate-registration

  20. lucastex on March 27th, 2009


    That’s it! Providing proxy information grails will use this to reach the jar and download it.

    Thanks a lot!

  21. Dennis Carroll on March 27th, 2009

    The Users in Bootstrap were not getting saved. Has to add to User.groovy:
    or provide a description

  22. fauzan on April 1st, 2009

    Hi there! Great tutorial! Just a comment, in the Permissions Management section, you forgot to mention that we need def authenticateService in BootStrap.groovy, although it’s mentioned in the final BootStrap.groovy. Thank you!

  23. lucastex on April 1st, 2009


    Thanks for your note! :)

  24. plustick on April 2nd, 2009

    I just found miss typed that the follow line.
    it will not working. please check it :)

    security.defaultRole = “USER_ROLE”
    [Wish to fix]
    security.defaultRole = “ROLE_USER”

  25. lucastex on April 2nd, 2009


    Thanks! That’s correct!

  26. Jet on April 7th, 2009

    Hi Lucas,

    Thanks for the wonderful tutorial.

    My request mapings are in the SecurityConfig.groovy file, and my user, role creations are in the BootStrap.groovy.

    But when I run the application, it failed.

    Any ideas


  27. lucastex on April 7th, 2009


    What is happening ?

  28. Jet on April 7th, 2009

    Hi Lucas,

    It is sorted.

    Just noticed that the automatically generated table ‘User’ in MySQL, all the fields there are “not null”.

    If my user created is like:

    def userAdmin = new User(username:’admin’,
    enabled: true,
    passwd: authenticateService.encodePassword(‘admin’)).save(flush: true)

    It will fail. But if I create a user like:

    def userAdmin = new User(username:’admin’,
    enabled: true,
    email: “joe.blog@abc.com”,
    emailShow: true,
    description: ‘admin’,
    passwd: authenticateService.encodePassword(‘admin’)).save(flush: true)

    It will be ok.

  29. Pedro Herrera on June 7th, 2009

    Ola Lucas,

    Como eu faço para fazer a autenticação utilizando e-mail ? outra dúvida, as informações do usuario ficam na session ? como eu resgato o nome do usuario para exibir na tela ?

    Valeu !!

    Pedro Herrera

  30. Lucas Teixeira on June 8th, 2009

    Oi Pedro,

    Para usar o e-mail ao invés do campo de usuário? Para não perder todas as funcionalidades que o plugin traz, eu faria com que o e-mail dele fosse automaticamente o valor do userName. Com isso você ainda consegue tratar esta informação como “nome de usuário mesmo”.

    Para resgatar o valor do usuario da sessão, você pode fazer tanto no GSP (usando a taglib AuthorizeTaglib) e se for no controller, pode usar o AuthenticateService. Ambos estão cobertos no item 7 deste tutorial!


  31. vennela on July 14th, 2009

    Hi ,

    Do you have Ajax login example .


  32. MK on August 17th, 2009


    Thank you so very much for sparing time and efforts to put this up. It’s informative and instructive both.


  33. Pedro Herrera on February 10th, 2010

    Ola Lucas, blz ?

    estou analisando o acegi para um projeto aqui na empresa. O problema que tenho é que um usuario pode ter um papel diferente para cada area. Ex : Pedro é ADM no depto GERINF, mas Pedro é USUARIO_NORMAL no depto DCHI. Pelo que percebi o acegi vincula cada usuario com o perfil(role). Tem como configurar o ACEGI para aceitar autorizações dessa forma ? Tem algum outro plugin que vc recomenda ?

    Abraços !!!

    Pedro Herrera

  34. [...] Review this excellent blog post regarding security configuration [...]

  35. [...] Review this excellent blog post regarding security configuration [...]

  36. Max on January 26th, 2011

    Check out the example of secure Grails application working with mongodb:


Leave a Reply

Web Analytics