Colin Harrington

Grails (Jetty) and crossdomain.xml

by Colin on Jul.13, 2008, under Groovy-Grails

Grails LogoThis last April I did a presentation at the Twin Cities Code Camp on Microsoft Silverlight and SOA with a Grails server.  I ended up writing a simple Grails application that used several web services to communicate to an in-browser Silverlight application.  I specifically wanted to show a Silverlight application interacting with non Microsoft Technologies.  I developed the Grails application on Linux on a different physical machine than what I used to develop the Silverlight application.

One of the Issues I ran into was that I was unable to make requests to the XML Web Services in the Grails application.  It puzzled me for a minute until a quick Google search turned up a simple issue: I needed a crossdomain.xml policy file (or the clientaccesspolicy.xml).  Flash/Flex users run into this all the time and thus most of what you will find is Flash centric.  What is the crossdomain.xml file?  Well its a way of restricting the domains that can access services.  Its basically a white-listing of domains that are allowed to access the services.  The browser and in-browser applications are supposed to respect the crossdomain.xml, and sometimes the Services (server-side) may protect themselves.  You can think of it as a robots.txt for Web services.

Great, I knew what the problem was, now how do I fix it?  I tried a few things, deploying to tomcat, but that didn’t work for me while I was actively developing the application.  Once I understood a little more about Grails and Jetty, I realized that I could just modify the Jetty server that launched when invoking grails run-app.  I simply had to add another context to Jetty, and bingo it worked.  Here is what I did:

I found Grails’ RunApp.groovy script (the one that gets invoked on grails run-app) which was located at $GRAILS_HOME\scripts\RunApp.groovy. (%GRAILS_HOME%\scripts\RunApp.groovy for you Windows folk ).  I had to simply create another context much like the Grails application context was being created.  Here is a stripped down example of what RunApp.groovy looked like. (modifications in Bold)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/**
 * Gant script that executes Grails using an embedded Jetty server
 *
 * @author Graeme Rocher
 *
 * @since 0.4
 */
...
grailsContext = null
rootContext = null
...
target( configureHttpServer : "Returns a jetty server configured with an HTTP connector") {
    ...
    setupWebContext()
    setupRootWebContext()
    server.setHandler( webContext )
    server.addHandler( rootContext )
    ...
}
target( setupRootWebContext: "Sets up the Secondary Root Context"){
    rootContext = new WebAppContext("${basedir}/web-app-root","/")
}

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Most of the magic is in the rootContext = new WebAppContext("${basedir}/web-app-root","/") line.  Notice that I had to create a new folder ‘web-app-root’ which resided alongside web-app (I think I used web-app for a while too).  So this context responds to everything in the "/" domain which is the root of the site.  Once I put my crossdomain.xml file in that folder, I could access http://localhost:8080/crossdomain.xml and the services were then accesible via Silverlight — Yay!

I’m sure there are better ways of doing this, but this is what I did to get the job done.  Thanks to JT Dev for his most recent post, which reminded me that I was going to blog about this.  I basically did Solution #2 in his blog post on creating multiple jetty contexts.  Where was this post back in March?  Thanks JT for tipping me off to the Static Resources Plugin!

 

 

:, , , ,

3 Comments for this entry

  • James Ward

    One of the great things about Flash is that it allows you to get around the same domain security policy in the browser. But this feature can open some significant security holes. Two general rules of thumb when using crossdomain.xml files:
    1) Never use a * policy on a website that uses cookies
    2) Never use a * policy on an internal / intranet website

    If you control the client that is running a Flash application making a crossdomain request then a better alternative to the crossdomain.xml file is to add the application to the Flash Player Trust list:
    http://livedocs.adobe.com/flex/3/html/help.html?content=security2_25.html

    I hope that helps.

    -James

  • Heather

    This is almost exactly what I have been looking for! However, the Jetty server I am working with is configured via xml. Would you know the proper syntax to do what you did here in a jetty.xml file?

  • Colin

    Just FYI, Grails has come a long way since I wrote this post. now you would just set
    grails.app.context = “/”
    In grails-app/conf/Config.groovy for the right environments

1 Trackback or Pingback for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!