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/GSecurityNow you can test it with
cd GSecurity grails run-appand 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-templatescreates 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. ;-)
9 comments:
Excellent post - thanks alot for showing how it's done.
thank you for this posting, this is a good starting point for securing a grails app. waiting for part 2 - how can i identify a user in my app?
great post, waiting for the rest in the series
Great how-to. Would love to see the next installment in the series!
Thanks to you and Mattias for pointing me in the right direction. I'm new to Grails, but I've using Spring Security in Java apps.
Hi,
I am following your posts about spring security in grails and loving them. However, I don't know if it is an error, but I have had problems with the configuration you provided.
I tried to create a taglib like you suggest in you next post, but kept getting null in the authentication object, suggesting not logged in even though I was logged in. The problem was the orders of the filters in web.xml. Apparently the sitemesh filter has to be AFTER the security filter, for everything to work.
Just so you know.
// Andréas
I'm a little bit late on this one but you make my day.
thanks
awesome post.. You do not know how many times I am referring this post while implementing spring ldap security with grails.
Excellent!
Could you please describe me how to configure the Grails with CAS.
I configured the CAS and its working fine but now I want to configure my grails application with CAS by using the Spring-Security-CAS plugin but HOW?
Could you please describe me step by step how to implement this?
Regards,
BSK
Post a Comment