There are two primary ways to configure the request mapping to secure application urls using the Acegi plugin. Additionally, @Secured annotations can be used on service methods and work is being done to integrate ACLs, but these won't be discussed here.
The goal is to create a mapping of urls and url patterns to the roles required to access those urls. Typically this is done with a static string of the form:
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /login/**=IS_AUTHENTICATED_ANONYMOUSLY /admin/**=ROLE_USER /book/test/**=IS_AUTHENTICATED_FULLY /book/**=ROLE_SUPERVISOR /**=IS_AUTHENTICATED_ANONYMOUSLY
and this approach is supported in the Acegi plugin in the 'requestMapString' property - set 'useRequestMapDomainClass' to false to enable reading this configuration.
The other supported mechanism stores mapping entries in the database, using the Requestmap domain class. Requestmap has a 'url' property which contains the secured url and a 'configAttribute' property containing a comma-delimited list of required roles.
Creation of Requestmap entries is the same as all Grails domain classes, e.g.
new Requestmap(url: '/login/**', configAttribute: 'IS_AUTHENTICATED_ANONYMOUSLY').save() new Requestmap(url: '/admin/**', configAttribute: 'ROLE_USER').save() new Requestmap(url: '/book/test/**', configAttribute: 'IS_AUTHENTICATED_FULLY').save() new Requestmap(url: '/book/**', configAttribute: 'ROLE_SUPERVISOR').save() new Requestmap(url: '/**', configAttribute: 'IS_AUTHENTICATED_ANONYMOUSLY').save()
Each approach has its advantages and disadvantages. The static string is less flexible since it's configured once in the code and can only be updated by restarting the application. In practice this isn't that serious a concern since for most applications, security mappings are unlikely to change at runtime.
If you want runtime-configurability then storing Requestmap entries enables this. There's a cost however, since each request triggers a Hibernate query to find applicable rules for the current request. But this allows you to have a core set of rules populated at application startup and to edit, add, and delete them whenever you like. If you run the generate-manager script (described here) you can use the CRUD GSPs generated at grails-app/views/requestmap, or you can create your own admin UI.
Some notes:
- for performance reasons, static resources are not checked since this would cause a lot of database requests. So if you need to restrict access to images, CSS, JavaScript files, etc. then you'll need to use the static mapping
- to understand the meaning of IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED, and IS_AUTHENTICATED_ANONYMOUSLY, see the Javadoc for AuthenticatedVoter
- urls must be mapped in lowercase, so for example if you have a FooBarController, its urls will be of the form /fooBar/list, /fooBar/create, etc. but these must be mapped as /foobar/**, /foobar/list, /foobar/create