Last updated by paul.atwork 5 years ago

Basic Tutorial using Standard String Mapping

There are three ways to define security mappings - see Securing URLs for more details. This tutorial uses the standard string mapping approach. To use Controller annotations, use this tutorial and to specify security mappings using database Requestmap entries use this tutorial.

Create your Grails application

# grails create-app bookstore
# cd bookstore

Install the Spring Security plugin

# grails install-plugin acegi

Create the User, Role, and Requestmap domain classes

# grails create-auth-domains User Role Requestmap
You can choose other names for User, Role, and Requestmap, and can create them in packages; these are just examples.
Note: Depending on your database, some names might not be valid. This goes for any domain classes you create, but names for security seem to have an affinity towards trouble. So before you use names like "User" or "Group", make sure they are not reserved keywords in your database :)
The script will create this User class:
/**
 * User domain class.
 */
class User {
   static transients = ['pass']
   static hasMany = [authorities: Role]
   static belongsTo = Role

/** Username */ String username /** User Real Name*/ String userRealName /** MD5 Password */ String passwd /** enabled */ boolean enabled

String email boolean emailShow

/** description */ String description = ''

/** plain password to create a MD5 password */ String pass = '[secret]'

static constraints = { username(blank: false, unique: true) userRealName(blank: false) passwd(blank: false) enabled() } }

and this Role class:
/**
 * Authority domain class.
 */
class Role {

static hasMany = [people: User]

/** description */ String description /** ROLE String */ String authority

static constraints = { authority(blank: false, unique: true) description() } }

and this Requestmap class:
/**
 * Request Map domain class.
 */
class Requestmap {

String url String configAttribute

static constraints = { url(blank: false, unique: true) configAttribute(blank: false) } }

Optional - create controllers and GSPs for User, Role, and Requestmap domain classes

# grails generate-manager
will create:
  • grails-app/controllers/RequestmapController.groovy
  • grails-app/controllers/RoleController.groovy
  • grails-app/controllers/UserController.groovy
  • grails-app/views/requestmap/create.gsp, edit.gsp, list.gsp, view.gsp
  • grails-app/views/role/create.gsp, edit.gsp, list.gsp, view.gsp
  • grails-app/views/user/create.gsp, edit.gsp, list.gsp, view.gsp
Note that these generated files are not part of the plugin - these are application files. So you're free to edit them however you like - they're examples to get you started. You could also generate standard Grails controllers and GSPs using

# grails generate-all User
# grails generate-all Role
# grails generate-all Requestmap

although for this tutorial I assume you're using the plugin-generated files.

Optional - create controllers and GSPs for Captcha, Register, and an Emailer Service.

# grails generate-registration
will create:
  • grails-app/controllers/CaptchaController.groovy
  • grails-app/controllers/RegisterController.groovy
  • grails-app/services/EmailerService.groovy
  • grails-app/views/register/edit.gsp, index.gsp, show.gsp
Again note that these generated files are not part of the plugin - these are application files that you're free to edit and customize.

Optional - delete Requestmap files

Since you'll be storing security mappings statically in SecurityConfig.groovy and not using the Requestmap class or database table, you can delete the Requestmap domain class and all references to it.

First delete the following:

  • the GSPs (grails-app/views/requestmap/*);
  • the Controller (grails-app/controllers/RequestmapController.groovy); and
  • the Domain object (grails-app/domain/Requestmap.groovy).
Then edit the file 'grails-app/conf/SecurityConfig.groovy':
  • remove the 'requestMapClass' property; and
  • add a new property 'useRequestMapDomainClass' and set it to false. So the resulting file will contain
useRequestMapDomainClass = false
loginUserDomainClass = "User"
authorityDomainClass = "Role"
/* requestMapClass = "Requestmap" */

Create a controller that will be restricted by role

# grails create-controller Secure
This will create grails-app/controllers/SecureController.groovy - add some output so we can verify that things are working:
class SecureController {
   def index = {
      render 'Secure access only'
   }
}

Start the server

# grails run-app
Before we secure the page, navigate to http://localhost:8080/bookstore/secure to verify that you can see the page without being logged in:

Create security mappings

Stop the server and edit grails-app/conf/SecurityConfig.groovy:

  • ensure the 'useRequestMapDomainClass' property exists and is set to false
  • add a 'requestMapString' property and set its value to:
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT

/secure/**=ROLE_ADMIN

so the resulting file will be

security {

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

active = true

loginUserDomainClass = "User" authorityDomainClass = "Role"

useRequestMapDomainClass = false

requestMapString = ''' CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT

/secure/**=ROLE_ADMIN ''' }

Note: If your controller class names have a capital letter in the name (other than the first character, e.g. BigCar or BigTruck), then the url you provide here should be something like "/bigcar/**" or "/bigtruck/**". The url you would expect to put in (i.e. "/bigCar/**" or "/bigTruck/**") will not work since the default behavior is to convert the url to lowercase before comparing with security rules.

Restart the server

# grails run-app

and navigate to http://localhost:8080/bookstore/role/create and create an 'admin' role:


and finally navigate to http://localhost:8080/bookstore/user/create to create a test user:

Now navigate again to http://localhost:8080/bookstore/secure and this time, you should be presented with the login page:

Log in with the username and password you used for the test user, and you should again be able to see the secure page:

When logging in, you can test the Remember Me functionality. Check the checkbox, and once you've tested the secure page close your browser and re-open it. Navigate again the the secure page, and since you have a cookie stored, you shouldn't need to log in again. Logout at any time by navigating to http://localhost:8080/bookstore/logout