Category Archives: Grails

JSONP in Grails Using Nothing But a Filter

Grails is a great platform for creating RESTful APIs. It comes with object serialization and formatting for XML and JSON out of the box, and it’s pretty easy to make your own custom builder if you decide you need some additional power.

One (at least in my mind) obvious use for a RESTful API would be calls from a third party (read: outside your application) JavaScript client using XMLHttpRequest (sometimes called AJAX). The current somewhat kludgey method to achieve this from the client is JSONP.

JSONP relies on a callback parameter which automatically formats the resulting JSON from the API. Just about every example of enabling JSONP in a Grails application I could find on Google and Stack Overflow was similar to

render "${params.jsoncallback}(${user as JSON})"

which meant it had to be in every controller that used it (somehow).

I wanted to enable JSONP across a bunch of existing controllers in my application and I decided a good way to do this would be a Grails filter. To do this in a Grails filter, you have to decide not to render your result from the controller (which isn’t necessarily a bad thing) and simply return it. An example:

def filters = {
   all(controller: '(jsonController1|jsonController2)', action: '*') {
     before = {
     }

     after = { model ->
       String resp = model as JSON
       if(params.callback) {
         resp = params.callback + "(" + resp + ")"
       }
       render (contentType: "application/json", text: resp)
       false
     }
     
     afterView = {
     }
   }
 }

This example is relatively simple and assumes that everything is coming back as JSON and that any call with the callback parameter is JSONP. However, it should be an easy starting point to create more sophistication if necessary.

Advertisements

Grails Less CSS Plugin

Recently, the LessCSS project was ported from Ruby to Node (JavaScript). This makes my implementation of the plugin obsolete. Please checkout David Marquis’ Blog for a much nicer Rhino implementation. I’m keeping this post here for historical purposes.

If you use CSS and think it might be one of the most needlessly complex parts of web development (as I do), Less CSS might be worth taking a look at. It’s been described as “CSS 4 from the futurez!” and, after using it on a few small projects, I really like it.

While some really cool projects exist to help integrate Less into your specific platform (check out .less for .NET projects, less.app for a great OS X front end app, and Less for Java as just a handful of examples), there didn’t exist anything yet for Grails.

Enter the Grails Less CSS plugin! As of right now, the plugin is in a very alpha state and works as follows:

  • Install the plugin (see below).
  • Place your .less files in the webapp/css directory (where your .css files would go)
  • Reference style sheets in your HTML as if the less files had a .css extension (e.g. a main.less file would be in your header as main.css).
  • Whenever a .less file changes, the associated .css file will be refreshed as well.

The Good

  • The plugin uses the Asual (see above) Java library which, in turn, uses JRuby to run the original Ruby project. The good thing about this approach is that this plugin can easily keep pace with the Ruby project and incorporate the latest features and bug fixes.
  • There is no longer any need to checkin .css files to your source repository as these can be considered “scratch” files that are easily regenerated from the .less source (similar to .groovy and .class files: the .groovy file is the one that really matters).

The Bad

  • Currently, the plugin pulls the entire JRuby library into the project. This adds some resource overhead and, although it’s fast once it gets running, it adds an approximate 3 second load time to the project.
  • There is no differentiation (yet) between development and production environments. As such, the plugin continues to run as part of the application in, say, a WAR deployed on Tomcat even though there is (probably) no reason for it to. I’m working on fixing this in a future update.
  • Less files that fail to properly compile generate really nasty stack traces and crash Grails. The messages are accurate and help diagnose the error, but it would be better to handle the exceptions in a better way (this is coming soon as well).

Installing

The plugin hasn’t yet been approved as a bonafide Grails plugin by the plugin community. Until then, visit the Github repository and download the grails-lesscss-0.1.zip (or whatever the latest version is) file. After it is downloaded, type

grails install-plugin [plugin filename.zip]

This is a work in progress, so feel free to give me some feedback and check out the source on Github!

Grails Acegi Plugin and Securing Multiple Resources using Basic Authentication

Grails is pretty awesome. Not only does it use Groovy as its main language, but it also provides nice DSL access to Spring settings.

Securing a website is something that can often be fairly complex and easy to get wrong. Grails provides a plugin for the state-of-the-art security model Spring Security (also called Acegi) (plugin can be found here).

Everything was all well and good until I tried to use two different security models simultaneously: a form-based login for human beings and an http basic authentication login for machines consuming an API.

This turned out to be pretty hard. The plugin requires setting the following in the resources.groovy file to work with basic authentication at all:

beans = {
  authenticationEntryPoint(org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint) {
    realmName = 'Grails Realm'
  }
}

(The plugin is supposed to automatically do this by setting the basicProcessingFilter = true flag in the SecurityConfigure.groovy file, but there is a bug as of version 0.5.2 which is, as of now, the latest production release.) This worked for basic authentication, but would no longer redirect users to the form-based login.

Back to the drawing board.

What I discovered was that I could change between using the form-based login or the http headers authentication but not use them both. (I should clarify this by saying that I could shove the headers into the request and it would work, but a challenge response of 401 was not being sent back to the client which technically breaks the http authentication spec.) I found this thread (with contributions from the author of the Acegi plugin itself) but, while it pointed me in a nice direction, it didn’t answer the question fully. What I really needed was a way to use the URL to decide how to authenticate.

I finally discovered that the ExceptionTranslationFilter was not unique for the URLs I was using. In short, if the URL looked like: http://www.test.com/application/api/user/show/1, I wanted to use basic authentication and if the URL was http://www.test.com/application/user/show/1, I wanted to use the form-based authentication. The redirect is controlled by the ExceptionTranslationFilter and there was only one (so only one model would work at a time).

All I ended up having to do is create my own ExceptionTranslationFilter and wire it to the API URL. The final code in resources.groovy looks as follows:

import org.springframework.security.util.FilterChainProxy
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsAccessDeniedHandlerImpl
import org.springframework.security.ui.ExceptionTranslationFilter

// Place your Spring DSL code here
beans = {
  basicAuthenticationEntryPoint(org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint) {
    realmName = 'Grails Realm'
  }

  basicExceptionTranslationFilter(ExceptionTranslationFilter) {
    authenticationEntryPoint = ref('basicAuthenticationEntryPoint')
    accessDeniedHandler = ref('accessDeniedHandler')
    portResolver = ref('portResolver')
  }

  springSecurityFilterChain(FilterChainProxy) {
    filterInvocationDefinitionSource = """
         CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
         PATTERN_TYPE_APACHE_ANT
         /xml*/**=authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,basicExceptionTranslationFilter,filterInvocationInterceptor 
         /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
         """
  }
}

Now, visiting any URL that prefixed by a /xml/ will be a call to the basic authentication headers and every other prefix will be a standard form-based login.

Since I shaved a serious yak figuring this out, I hope it helps someone!