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. ;-)