Sunday, November 13, 2016

Upgrading Grails-2 application to Grails-3 - Make static assets available . . .

Recently, I started upgrading a Grails web-application from Grails-2 to Grails-3, particularly from version 2.2.1 to 3.2.1. The perfect minor.patch(2.1) matching of both versions in this process was just a perfect timing-coincidence as Grails was at 2.2.1 when this app was developed and the latest Grails was at 3.2.1 when I started to upgrade.

The process of upgrading was not bad, but it required quite a bit of careful changes. I simply followed the very well documented Grails3 Documentation and get going this effort after successfully migrating an in-house plugin ZipCityState from Grails-2 to Grails-3. This deserves another blog post.

Static Assets

One of the web aspects that needed bit more effort in this upgrade was: Static Assets.

Grails-3 comes with asset-pipeline plugin. Static assets like images, javascript and stylesheets need an upgrade by moving from Resources plugin to Asset-pipeline plugin. There is a nice blog post on this from Grails Team and according to this, the viable option in Grails-3 is asset-pipeline and resources plugin is not available. I will write a bit more detailed post on this later.

After upgrading the application and taking care of several compilation and startup issues along the way, I was finally able to get the application started and running. The login page showed up but all the static assets like stylesheets, javascripts and images were totally missing. This made me look into all asset pipeline directives and related changes I made in migrating static assets to asset-pipeline. Everything looked good but the issue was just puzzling. After spending sometime finally I realized that static assets upgrade to asset-pipeline from Grails-2 to Grails-2 need some attention from security settings as well.

Grails Spring Security Plugin takes a pessimistic locks down approach and locks down all URLs that do not have an applicable URL mapping. 

Usually, Grails-2 security static rules look like:
grails.plugins.springsecurity.controllerAnnotations.staticRules = [ '/login/**': ['IS_AUTHENTICATED_ANONYMOUSLY'], '/js/**': ['IS_AUTHENTICATED_ANONYMOUSLY'], '/css/**': ['IS_AUTHENTICATED_ANONYMOUSLY'], '/images/**': ['IS_AUTHENTICATED_ANONYMOUSLY'], '/**': ['IS_AUTHENTICATED_FULLY'] ]

In Grails-3, add pattern 'assets/**' for static assets as they are now moved under grails-app/assets and get served by asset pipeline plugin through requests URLs like- http://my-app-url/assets/.  Make the static rules look like the following (highlighted is the change):
grails.plugin.springsecurity.controllerAnnotations.staticRules = [ [pattern: '/login/**', access: ['IS_AUTHENTICATED_ANONYMOUSLY']], [pattern: '/assets/**', access: ['IS_AUTHENTICATED_ANONYMOUSLY']], [pattern:'/**', access: ['IS_AUTHENTICATED_FULLY']] ]

There you go, asset pipeline plugin works and all static assets are available, get served and become visible!


No comments: