SpringOne2GX, Day 2 Recap

Another good day at SpringOne.

The first session of the day was with Burt Beckwith going over the Spring Security plugin(s) for Grails. The last Grails work I did was with the Shiro/JSecurity plugin, which worked well, but I’ve always been interested in the extended feature set of Spring Security and it’s extensions. I thought the UI plugin looks useful, and the OpenID support looks like it’s got some nice features. Much of the rest still seems to be up in the air, but it’s maturing nicely. Glad to hear the demo code will be available.

Second talk was on the Google track, and was covering Spring Roo (which I promptly got stoked about yesterday) and it’s integration with GWT. I understand all of the browser compatibility advantages of GWT, but I’m still not convinced the complexity is worth it. Thankfully, Spring Roo does what it does best when it comes to GWT – generates and tucks away your boiler plate code. I’m not as excited about GWT as I thought I would be.

Third talk was with Burt Beckwith again – this time about strategies for handling database migrations in Grails apps. This is an aspect of Rails that I think is far superior to Grails. I didn’t get much from this talk other than how to correctly use Liquibase, but it was good to hear that this is something is being addressed in the upcoming version of Grails.

Fourth talk was about Extreme Scaffolding with Jean Barmash. We saw demos of a few interesting plugins for scaffolding and other UI enhancements, but I didn’t see anything really groundbreaking. It seems that a good command of grails templates, layouts and keeping DRY in mind would accomplish the same thing. It might even take longer to put all of these plugins in, and learn how to correctly use them, rather than just focus on writing good code and pushing out useful functionality.

Finishing the day with Stefan Schmidt and another great talk on the versatile persistence functionality available in the latest version of Spring Roo. The incremental reverse engineering is awesome and blows hibernate right out of the water. Grails and Rails are great for greenfield development, but this really makes Roo a compelling solution for developing new apps on existing databases. The JPA2 and NoSQL support were interesting. The one part I didn’t get was the discussion on Hades. Hades is a Roo add-on that generates the DAOs that Roo is made to get rid of (or at least hide). Maybe I missed something – it sounded interesting – I just didn’t see how it fit with the rest of the features of Roo, other than code generation, of course.

In all, not as good a day as the first, but I learned some interesting things. Spring Roo really seems like an exciting alternative Grails, especially if you’re developing in a dynamic language resistent environment. Looking forward to tomorrow.

Shiro/Grails Tips

The Shiro plugin page in the Grails plugin repository has great information. Here are a couple of additional items I picked up during an implementation on my current project:

1. Filter every action except ‘x’ on a given controller

	    myFilter(uri: '/myController/**') {
	      before = {
	        if (!controllerName || actionName == "anOpenAction" || actionName == "anotherOpenAction") return true

	        // Access control by convention.
	        if (!isErrorPage(controllerName, actionName)) {

In this case, we’re taking advantage of common properties in grails. Basically, we’re filtering actions on myController. The first ‘if’ clause (!controllerName) filters for direct/default controller views, ignoring direct views. The other clauses are saying ‘if we’ve hit this filter, but the actionName is ‘anOpenAction’ or ‘anotherOpenAction’, let the request through.

2. Simple landing pages – enhancing the ‘free’ Shiro AuthController

If there is no target URI on the user’s original request to login, meaning, if they weren’t challenged and instead clicked on a ‘login’ link, a simple way to control where they are directed (assuming the goal is not to direct them to ‘/’) is as simple as this (with source from the AuthController):

	// If the user came to the login page via redirect (security filter caught an attempt to
	            // go to a restricted area of the site), then send them back from whence they came.
		        def savedRequest = WebUtils.getSavedRequest(request)
		        if (savedRequest) {
		            targetUri = savedRequest.requestURI - request.contextPath
		            if (savedRequest.queryString) targetUri = targetUri + '?' + savedRequest.queryString
		            println "Target URI, from saved request: ${targetUri}"
		        else {
		            // If a controller redirected to this page, redirect back
			        // to it. Otherwise redirect to an appropriate URI depending on the
		            // role of the user who just logged in.
		        	if(params.targetUri) {
		        		targetUri = params.targetUri
		        	else {
		        		targetUri = //some bit of code that determine the URI from the current user, etc.

Where that last reference of ‘targetUri’ is somehow set to where you want your newly-authenticated user to land.