Wednesday, February 17, 2016

Grails3 and Spring Security

ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[grailsDispatcherServlet] - Servlet.service() for servlet grailsDispatcherServlet threw exception
java.lang.IllegalStateException: There was a problem retrieving the current GrailsWebRequest. This usually indicates a filter ordering issue (the 'springSecurityFilterChain' filter-mapping element must be positioned after the 'grailsWebRequest' element when using @Secured annotations).

This issue was bugging me on a new grails3 and spring security web application. It turns out there are more than few active bugs on this issue. I filed my own:

https://github.com/grails-plugins/grails-spring-security-core/issues/412

After a week of noodling on the issue and trying various leads - the root cause seems to be spring security is delegating to the embedded tomcat error pages for routes only covered by static rule mappings (while your application is still using annotations). Instead, the plugin should correctly delegate to your mapped errors pages within the grails system. Included in the above post is my work around, which I will repeat here. This will cause all errors encountered within static routes to use the correct mappings.

You must setup an error controller:

class ErrorController {

    def error() {
        render view: 'error'    }

    def invalid() {
        render view: 'error'    }

    def denied() {
        render view: 'denied'    }

    def notFound() {
        render view: 'notFound'    }
}

And use this controller within your URL mappings:

"400"(controller: "error", action: "invalid")
"500"(controller: "error", action: "denied")
"403"(controller: "error", action: "denied")

"404"(controller: "error", action: "notFound")


And finally disable the spring-secuurity error page within application.groovy

grails.plugin.springsecurity.adh.errorPage = null




FlowJs Upload Reciever for Grails

I chose flow.js (https://github.com/flowjs/flow.js) for my client side file uploading due to its fault tollerance. I use using the ng-flow (https://github.com/flowjs/ng-flow/) angular library that builds an excellent set of directives around the framework. The one downside is the lack of documentation on what it takes to build a server side compliment to this. The particular beckend I am using is Grails3 based (although this would work for earlier versions of grails with little modification).

I built a service that can be plugged into multiple controllers to achieve the effect. While I wont publish the whole service, here is a skelleton that should be enough to get you started.