2010-04-27

Securing Grails with Spring Security, Part 2


Welcome back to part 2 of Securing Grails with Spring Security.
In part 1 we made the basic configuration to connect Spring Security and Grails.

In this second part we will write a tag library which we will later use to show and hide parts of a page, determine wether the client is authenticated and display the name and roles of the logged in user.

This second part is heavily inspired by the Grails Security plugin by Tsuyoshi Yamamoto et al. Most of the sourcecode is in fact copied from their plugin.

Setup

We will need a couple of files and directories, so let's create them right away.
grails create-controller com.acme.Secure
The index method of this controller is sufficient. But we need an index.gsp in grails-app/views/secure.

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="layout" content="main" />
    <title>Secure</title>
  </head>
  <body>
    <h1>This page is secured</h1>
    --- we'll add our payload here ---
  </body>
</html>

grails create-tag-lib com.acme.Security

The taglib should provide the following functions:
  1. Output the body of the tag if the user is authenticated/not authenticated
  2. Output the authenticated principal (if any)
  3. Output the roles of the authenticated principal (if any)
  4. Output the body of the tag if the user has all, none or any roles of a specified set of roles
We'll write some helper methods which we will reuse later.

Foundations

The most important object in Spring Security is the SecurityContextHolder. By default this is a ThreadLocal which stores the security context of the application, which will be our entry point to all security related information we need. (I suggest reading the great documentation for Spring Security if you want to know the gory details.)
To save us some typing we'll declare a shortcut (thanx Groovy)
import org.springframework.security.core.context.SecurityContextHolder as SCH
and a helper method
private boolean isAuthenticated() {
   def authPrincipal = SCH?.context?.authentication?.principal
   return authPrincipal != null && authPrincipal != 'anonymousUser'
}
The safe navigation operator (?.) makes sure that authPrincipal is null if one of SCH, context, authentication or principal is null. This means that we are not authenticated. The user may still be not authenticated if the authPrincipal is 'anonymousUser'. (See Spring Security docs for Anonymous Authentication)

isAuthenticated/isNotAuthenticated

Now our first two tags are easy to write:
def ifAuthenticated = { attrs, body ->
   if (isAuthenticated()) {
      out << body()
   }
}

def ifNotAuthenticated = { attrs, body ->
   if (!isAuthenticated()) {
      out << body()
   }
}
Using the taglib is similarly easy (in the payload section of index.gsp):
ifAuthenticated: <g:ifAuthenticated>** authenticated **</g:ifAuthenticated><br/>
ifNotAuthenticated: <g:ifNotAuthenticated>** not authenticated **</g:ifNotAuthenticated><br/>
When you reload this page it'll tell you wether you are logged in or not.
Play around with a couple of pages and different interception urls (Part 1) and see how the pages behave.

What's next

It may not seems so, but we covered a lot of ground so far. You should now have a basic orientation how to work with Spring Security at the taglib level.
In the next post of this series we'll talk about roles and the user principal.

No comments: