Enterprise Java

Grails with Spring Security

1. Overview of Spring Security Integration with Grails

Spring Security touts a number of authentication, authorization, instance-based, and various other features that make it so attractive to secure applications with.

With this in mind, due to Grails use of Spring’s Inversion of Control Framework and MVC setup, developers sought to use Spring Security to secure Grails.

This has resulted in two notable plugins: Spring Security Core Plugin and Spring Security ACL Plugin.

We will be reviewing the capabilities of these Spring Security plugins and making comparisons to using Spring Security for a plain old Spring application.

2. Spring Security Core Plugin

This plugin provides practical defaults with many configuration options for customization.

2.1 Domain Classes

The Spring Security Core Plugin uses the default Grails domain classes. In order to use the standard lookup for the plugin, we need at a minimum a Person and Authority domain class.

If we want to store URL <==> Role mappings in the database (which is one of several approaches for defining the mappings), we need a Requestmap domain class. If we use the recommended approach for mapping the many-to-many relationship between Person and Authority, we also need a domain class to map the join table.

To use the user/group lookup, we’ll also need a Group domain class. If we are using the recommended approach for mapping many-to-many relationship between Person and Group and between Group and Authority we’ll need a domain class for each to map the join tables. We can still additionally use Requestmap with this approach.

We can use the s2-quickstart to generate domain classes. The syntax is quite easy:

grails s2-quickstart DOMAIN_CLASS_PACKAGE USER_CLASS_NAME ROLE_CLASS_NAME [REQUESTMAP_CLASS_NAME] [--groupClassName=GROUP_CLASS_NAME]

An example with Person, Authority, and Requestmap:

grails s2-quickstart com.ourapp Person Authority Requestmap

2.2 Configuring Request Mappings for Securing URLs

We can choose among the following approaches to configure request mappings for securing URLs:

We can only use one method at a time.

For example, here is use of the @Secured annotation with Spring Expression Language (SpEL):

class SecureController {

   @Secured("hasRole('ROLE_USER')")
   def someRandomAction() {
      ...
   }

2.3 Various Other Features

Some various features of the Spring Security Core Plugin include:

  • Helper classes for dealing with lower levels of Spring Security, such as a SecurityTagLib that provides GSP tags to support conditional display based on whether the user is authenticated, and/or has the required role to perform a particular action.
  • Events – including event notifications, event listeners, and callback closures.
  • Filters, including the ability  to define which filters are applied to different URL patterns.

3. Spring Security ACL Plugin

The Spring Security ACL Plugin adds Domain Object Security support to a Grails application that uses the aforementioned Spring Security Core Plugin. So, we need to have that other plugin already in our build.gradle.

What does it mean to add Domain Object Security support? The Spring Security Core plugin and other extension plugins support restricting access to URLs via rules that include checking a user’s authentication status, roles, etc. and the ACL plugin extends this by adding support for restricting access to individual domain class instances.

3.1 Method Security

The four annotations typically available in Spring Security are available for use with Spring Expression Language (SpEL) expressions to perform Expression-Based Access Control:

  • @PreAuthorize
  • @PreFilter
  • @PostAuthorize
  • @PostFilter

The above annotations are all documented in the Method Security Expressions portion of the Spring Security documentation.

The ability to use method security is a very significant difference between the Spring Security ACL Plugin and the Spring Security Core Plugin. If we are to implement fine-grained access control, the Spring Security ACL Plugin is a must have for this reason.

Thankfully, besides the syntax differences between Groovy and Java, the code really looks the same:

@PreAuthorize("hasRole('ROLE_USER')")
   @PostFilter("hasPermission(filterObject, read) or " +
               "hasPermission(filterObject, admin)")
   List getAllDocs(params = [:]) {
      Report.list(params)
   }

3.2 Domain Classes

Like the Spring Security Core Plugin, the Spring Security ACL Plugin uses domain classes for appropriate structuring.

The domain classes, in this case, are used to manage database state. To be compatible with the typically JDBC-based Spring Security code, domain classes are created to generate the table and column names.

The classes in this plugin associated with persistence use these classes. However, they can be overridden by running the s2-create-acl-domains script:

grails s2-create-acl-domains

So, the script will generate the same domain classes in our application’s grails-app/domain folder to allow some customization.

3.3 Various Other Features

Some various features of the Spring Security ACL Plugin include:

  • Run-As-Authentication Replacement: this is a temporary authentication switch that only lasts for one method invocation.
  • Custom permissions: There are 5 permissions available from the BasePermission class: READWRITECREATEDELETE, and ADMINISTRATION. You can add your own permissions, if you need.
  • Tag library (taglib) for permit and deny.

4. Conclusion

The Spring Security Core Plugin offers a number of very useful features for securing Grails with Spring Security, but in order to implement more sophisticated, fine-grained authorization it is necessary to use the Spring Security ACL Plugin in conjunction.

Recommended reading: Authorizing Resources Based On Who Created Them (Spring Security) and my posts about the Spring Framework for general Spring knowledge.

Published on Java Code Geeks with permission by Michael Good, partner at our JCG program. See the original article here: Grails with Spring Security

Opinions expressed by Java Code Geeks contributors are their own.

Michael Good

Michael is a software engineer located in the Washington DC area that is interested in Java, cyber security, and open source technologies. Follow his personal blog to read more from Michael.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button