(Quick Reference)

2 What's New in Version 2.0 - Reference Documentation

Authors: Burt Beckwith, Beverley Talbott

Version: 2.0.0

2 What's New in Version 2.0

There are many changes in the 2.x versions of the plugin from the older approaches in 1.x.

Package changes

All classes are now in the grails.plugin.springsecurity package or a subpackage. The names tend to correspond to the analagous Spring Security classes where appropriate, for example MutableLogoutFilter is in the grails.plugin.springsecurity.web.authentication.logout package to correspond with the org.springframework.security.web.authentication.logout package.

Some of the changes were more subtle though; for example all classes in the old grails.plugins.springsecurity packages and subpackages are now in grails.plugin.springsecurity, only one character different. This will result in a non-trivial upgrade process for your applications, but that is a benefit as it will hopefully point you at other important changes you might have otherwise missed.

Configuration prefix changes

The prefix used in Config.groovy for the plugin's configuration settings has changed from grails.plugins.springsecurity to grails.plugin.springsecurity.

More aggressively secure by default

In 1.x it was assumed that defaulting pages to not be secured, and configuring guarded URLs as needed, was a more pragmatic approach. Now however, all URLs are initially blocked unless there is a request mapping rule, even if that rule allows all access. The assumption behind this change is that if you forget to guard a new URL, it can take a long time to discover that users had access, whereas if you forget to open access for allowed users when using the "pessimistic" approach, nobody can access the URL and the error will be quickly discovered. This approach is more work, but much safer.

This is described in more detail here.

Logout POST only

By default only POST requests are allowed to trigger a logout. To allow GET access, add this

grails.plugin.springsecurity.logout.postOnly = false

bcrypt by default

The default password hashing algorithm is now bcrypt since it is a very robust hashing approach. PBKDF2 is similar and is also supported. You can still use any message digest algorithm that is supported in your JDK; see this Java page for the available algorithms.

New applications should use bcrypt or PBKDF2, but if you didn't change the default settings in previous versions of the plugin and want to continue using the same algorithm, use these settings:

grails.plugin.springsecurity.password.algorithm = 'SHA-256'
grails.plugin.springsecurity.password.hash.iterations = 1

Session Fixation Prevention by default

Session Fixation Prevention is now enabled by default, but can be disabled with

grails.plugin.springsecurity.useSessionFixationPrevention = false

@Secured annotation

As of Grails 2.0, controller actions can be defined as closures or methods, with methods being preferred. The @Secured annotation no longer supports being defined on controller action closures, so you will need to convert them to real methods.

You can also specify the HTTP method that an annotation is defined for (e.g. when using REST). When doing this you must explicitly name the value attribute, e.g.

@Secured(value=["hasRole('ROLE_ADMIN')"], httpMethod='POST')
def someMethod() {
   …
}

In addition, you can define a closure in the annotation which will be called during access checking. The closure must return true or false and has all of the methods and properties that are available when using SpEL expressions, since the closure's delegate is set to a subclass of WebSecurityExpressionRoot, and also the Spring ApplicationContext as the ctx property:

@Secured(closure = {
   assert request
   assert ctx
   authentication.name == 'admin1'
})
def someMethod() {
   …
}

Anonymous authentication

In standard Spring Security and older versions of the plugin, there is support for an "anonymous" authentication. This is implemented by a filter that registers a simple Authentication in the SecurityContext to remove the need for null checks, since there will always be an Authentication available. This approach is still problematic though because the Principal of the anonymous authentication is a String, whereas it is a UserDetails instance when there is a non-anonymous authentication.

Since you still have to be careful to differentiate between anonymous and non-anonymous authentications, the plugin now creates an anonymous Authentication which will be an instance of grails.plugin.springsecurity.authentication. GrailsAnonymousAuthenticationToken with a standard org.springframework.security.core.userdetails.User instance as its Principal. The authentication will have a single granted role, ROLE_ANONYMOUS.

No HQL

Some parts of the code used HQL queries, for example in the generated UserRole class and in SpringSecurityService.findRequestmapsByRole. These have been replaced by "where" queries to make data access more portable across GORM implementatioins.

Changes in generated classes

The enabled property in the generated User class now defaults to true. This will make creating instances a bit more DRY:

def u = new User(username: 'me', password: 'itsasecret').save()

If you prefer the old approach, change your generated class.

Also, the plugin includes the grails.plugin.springsecurity.LoginController.groovy and grails.plugin.springsecurity.LogoutController.groovy controllers, and grails-app/views/auth.gsp and grails-app/views/denied.gsp GSPs. If you had no need previously to change these you can delete your files and the plugins' files will be used instead. If you do want to change them, copy each as needed to your application and make the required changes, and yours will be used instead.

One small change is that there is no longer a default value for the domain class name properties (userLookup.userDomainClassName, authority.className, requestMap.className, rememberMe.persistentToken.domainClassName). This was of little use and tended to cause confusing error messages when there was a misconfiguration.

SecurityContextHolder strategy

You can now define the SecurityContextHolder strategy. By default it is stored in a ThreadLocal, but you can also configure it to use an InheritableThreadLocal to maintain the context in new threads, or a custom class that implements the org.springframework.security.core.context.SecurityContextHolderStrategy interface. To change the strategy, set the grails.plugin.springsecurity.sch.strategyName config property to "MODE_THREADLOCAL" (the default) to use a ThreadLocal, "MODE_INHERITABLETHREADLOCAL" to use an InheritableThreadLocal, or the name of a class that implements SecurityContextHolderStrategy.

Debug filter

You can enable a "debug" filter based on the org.springframework.security.config.debug.DebugFilter class. It will log security information at the "info" level and can help when debugging configuration issues. This should only be enabled in development mode so consider adding the property that enables it inside an environments block in Config.groovy

environments {
   development {
      grails.logging.jul.usebridge = true
      grails.plugin.springsecurity.debug.useFilter = true
   }
   production {
      grails.logging.jul.usebridge = false
   }
}

Also add the implementation class name in your Log4j configuration:

info 'grails.plugin.springsecurity.web.filter.DebugFilter'

Storing usernames in the session

In Spring Security 3.0 and earlier, the username was stored in the HTTP session under the key "SPRING_SECURITY_LAST_USERNAME". This no longer done, but the plugin will use the old behavior if the grails.plugin.springsecurity.apf.storeLastUsername setting is set to true (the default is false ). Further, the name is no longer escaped before storing, it is stored exactly as entered by the user, so you must escape it when redisplaying to avoid XSS attacks.

@Authorities annotation

You can use the new @Authorities annotation to make your annotations more DRY. See this blog post for a description about the motivation and implementation details. Note that the package for the annotation in the plugin is grails.plugin.springsecurity.annotation, not grails.plugins.springsecurity.annotation as described in the blog post.

Miscellaneous changes

AuthenticationDetailsSource

Previously you could configure the details class that was constructed by the authenticationDetailsSource bean by setting the authenticationDetails.authClass property. In Spring Security 3.2 this isn't possible because WebAuthenticationDetailsSource always returns a WebAuthenticationDetails. But you can still customize the details class by creating a class that implements the AuthenticationDetailsSource interface, e.g.:

package com.mycompany;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.AuthenticationDetailsSource;

public class MyAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, MyWebAuthenticationDetails> {

public MyWebAuthenticationDetails buildDetails(HttpServletRequest context) { // build a MyWebAuthenticationDetails } }

and registering that as the authenticationDetailsSource bean in resources.groovy

import com.mycompany.MyAuthenticationDetailsSource

beans = { authenticationDetailsSource(MyAuthenticationDetailsSource) { // any required properties } }