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.

2010-04-15

eXaro

eXaro it's a free reporting solution for Qt (>=4.4) released under GPL (v3)/LGPL (v3) license.

2010-04-10

SmartGit

SmartGit is a graphical front-end for the distributed version control system Git and runs on Windows, Mac OS X and Linux.

SmartGit helps Git beginners getting started quickly and makes advanced users more productive with its efficient user interface to Git — the most powerful DVCS today.

SmartGit can be used free of charge for non-commercial purposes.

2010-04-08

Securing Grails with Spring Security, Part 1


What?

In part one of this series I want to show how easy it is to secure your Grails apps with a current version of Spring Security. It deals with the now current version of Grails (1.2.2) and Spring Security (3.0.2).

Why?

Grails as well as Spring are highly agile environments. Sometimes so agile that it is difficult to find plugins for current versions.
Although there are several approaches to securing Grails apps using plugins I wanted to stick to Spring Security. I have been very happy with it since the ancient days when it was called Acegi Security.
Unfortunatelly the plugins available either use a very different approach (eg Stark Security) or provide rather old versions of Spring Security (eg Spring Security Plugin 0.5.2 which uses Spring Security 2.0.4 under the hood).
This posting should show you how easy it is to expand Grails functionality if you cannot or don't want to use plugins.
This first installment slightly updates Mattias Hellborg Arthursson's posting Spring Security For Real with Grails.

How?

As it turns out it is quite easy to integrate Spring Security in Grails. I'm going to show you how in some easy to follow steps.

1. Download

Get Grails 1.2.2 and Spring Security 3.0.2 from the corresponding website, install Grails and unpack Spring Security to a location of your liking.

2. Create a Grails project and test it

lugaru> grails create-app GSecurity
Welcome to Grails 1.2.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /opt/grails

Base Directory: /home/lugaru
Resolving dependencies...
[...]
Created Grails Application at /home/lugaru/GSecurity
Now you can test it with
cd GSecurity
grails run-app
and browse to http://localhost:8080/GSecurity.

3. Install the web.xml template

Spring Security is based on an HTTP filter. These are normally configured in the web.xml, which we don't have in our Grails project, yet.
grails install-templates
creates some files and directories under src/templates. We only need src/templates/war/web.xml. You can safely delete src/templates/artifacts and src/templates/scaffolding.

Now edit src/templates/war/web.xml and add this after the last filter definition
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
and
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
after the last filter mapping. (Question: Is there a more grails-ish way?)

4. Install the libraries

Copy spring-security-config-3.0.2.RELEASE.jar, spring-security-core-3.0.2.RELEASE.jar and spring-security-web-3.0.2.RELEASE.jar from Spring Security to your Grails lib directory.

5. Configure the security filter

There are two ways to configure the security filter. Either you can declare your Spring beans in grails-app/conf/spring/resources.groovy or in grails-app/conf/spring/resources.xml (which you have to create first).
The following snipped uses the later option. It will password protect your whole application using basic authentication (the infamous password box). You can log in using one of the four users (user1, user2, user3, admin) with their corresponding password. We do not use their authorities/roles yet, but I'll need them in one of the later parts of this series.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    <http auto-config="true" use-expressions="true">
        <http-basic/>
        <intercept-url pattern="/**" access="isAuthenticated()" />
    </http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider>
            <user-service>
                <user name="admin" password="admin" authorities="ROLE_ADMIN"/>
                <user name="user1" password="user1" authorities="ROLE_GROUP1"/>
                <user name="user2" password="user2" authorities="ROLE_GROUP1,ROLE_GROUP2"/>
                <user name="user3" password="user3" authorities=""/>
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>
As you can see this is a standard Spring Security configuration.
Congratulations! You have done it.

But wait! This is not production ready at all. I have all my users and roles in an LDAP server. Can I use that, too?
Certainly!
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
             http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    <http auto-config="true" use-expressions="true">
        <http-basic/>
        <intercept-url pattern="/**" access="isAuthenticated()" />
    </http>

    <ldap-server url="ldap://localhost:389/dc=acme,dc=com" />
    <authentication-manager alias="authenticationManager">
        <ldap-authentication-provider user-search-base="ou=users"
                                      user-search-filter="(cn={0})"
                                      group-search-base="ou=groups"
                                      group-search-filter="(uniqueMember={0})"/>
    </authentication-manager>
</beans:beans>

Update: You'll also need to copy spring-ldap-1.3.0.RELEASE-all.jar and spring-security-ldap-3.0.2.RELEASE.jar to Grails lib directory.
The security namespace of Spring Security is very concise, this is the reason why I did not create the beans in resources.groovy. (Although I have to admit that I'm pretty new to Groovy and Grails and might have missed something which would have made it even more concise.)

What's next

From this point on it is almost trivial to expand the configuration to use remember-me, form-based authentication, session hijacking-protection and all the other fine things Spring Security has to offer. I strongly recommend to read the great documentation which comes with Spring Security.

In the next part of this series we will create a tag library which will allow you to show and hide information depending on user roles.

Disclaimer

This post would not have been possible without Mattias Hellborg Arthursson's Spring Security For Real with Grails which demonstrated that at least it is do-able.
I'm in no way an experienced Groovy or Grails developer. So all errors are mine.
The same goes for every funny phrase or wrong spelling. English is not my mother's tongue. I'm sure you've noticed that already. ;-)