Category Archives: GWT

Securing a GWT Grails app with Shiro

A recent poster on the Grails user mailing list asked how to secure a GWT application using Shiro. The Shiro Plugin is mostly designed to work with Grails controllers and GSPs, so that’s what the current documentation targets. GWT is a different kettle of fish, so can the Shiro Plugin help here?

As it happens, I needed to handle unauthenticated GWT requests myself recently. Here’s the solution I came up with.

Imagine we have a GWT-RPC request come in to the server, but the session has timed out. First off, is the request protected? That depends on how you have your security filters configured. I currently have this:

class SecurityFilters {
    def filters = {
        ...
        gwt(controller: "gwt", action: "index") {
            before = {
                accessControl { true }
            }
        }
        ...
    }
}

Because I’m protecting the “gwt” controller, all GWT-RPC requests require an authenticated (or remembered) user. That means whenever the current user’s session times out, Shiro kicks in and asks for authentication. It does this by redirecting to the login page, but this doesn’t work within the context of a GWT-RPC request. So what can you do?

The Shiro plugin allows you to customise the behaviour when the user requires authentication. Simply implement the following method in your filters class:

class SecurityFilters {
    ...
    def onNotAuthenticated(subject, filter) {
        if (filter.request.contentType?.startsWith("text/x-gwt-rpc")) {
            filter.render(text: "", status: 401)
            return false
        }
        else {
            // Not an AJAX request, so continue with the default behaviour.
            return true
        }
    }
}

If this method is implemented, the plugin calls it whenever authentication is required. In this particular case, I return a status of 401 (Unauthorized) if the request is of type GWT-RPC. Otherwise, I trigger the default behaviour (redirection to the login page) by returning true. In other words, the return value of the method determines whether the default behaviour occurs or not.

Note The return value of onNotAuthenticated() only has an effect in version 1.1-SNAPSHOT and greater of the plugin.

That’s it for the server side. All we need to do now is handle the 401 response on the client. How you exactly do this depends on your approach to GWT requests, but the basic mechanics are the same. I use the action handler mechanism supported by the plugin, along with Google Gin, so I can simply wrap the standard action service with a version that handles 401 responses:

public class SecureActionService implements GwtActionServiceAsync {
    private final GwtActionServiceAsync actionService;

    @Inject 
    SecureActionService(final GwtActionServiceAsync actionService) {
        this.actionService = actionService;
    }   
            
    public <T extends Response> void execute(final Action<T> action, final AsyncCallback<T> callback) {
        actionService.execute(action, new AsyncCallback<T>() {
            public void onFailure(Throwable caught) {
                if (caught instanceof StatusCodeException &&
                        ((StatusCodeException) caught).getStatusCode() == 401) {
                    // Authentication/authorisation failure. Assume
                    // authentication at this stage and redirect to
                    // login page.
                    final String loginUrl = GWT.getHostPageBaseURL() + "login";
                    Window.open(loginUrl, "_self", "");
                }
                else {
                    callback.onFailure(caught);
                }
            }
        
            public void onSuccess(T result) {
                callback.onSuccess(result);
            }
        });
    }
}

Now all the client code that has the action service injected gets the custom secure service instead. This particular implementation isn’t ideal because it redirects to the standard login page for a 401, whereas it would probably be better to have a simple login popup that then resends the action on successful authentication. However, the key point is that you need to implement the onFailure() method and check for a StatusCodeException. You can then do whatever you want with a 401 response.

The solution outlined above is fairly basic, particularly as it doesn’t deal with unauthorised (as opposed to unauthenticated) access, but it should provide you with a suitable starting point to implement your own solution. You can also see how powerful the command pattern is combined with the dependency injection provided by Google Gin.

One last thing to mention: all the above is geared towards GWT-RPC. If you prefer to use JSON for the client-server communication, then you’ll need a different approach. I have no experience yet on that side of things, but you should be able to check the HTTP headers in onNotAuthenticated to determine whether a request is from GWT or not. Alternatively, simply check for the JSON content type.

The Command Pattern with the Grails GWT Plugin

A talk by Ray Ryan of Google at the 2009 Google IO conference has caused a bit of a buzz in the GWT community. In that talk, Ray recommends several design patterns that will help make your projects more manageable as they grow in size. The particular suggestion I’ll be focusing on in this post concerns using the Command Pattern for server requests.

The idea is to encapsulate the stuff you want the server to do for your client in command or action objects instead of using standard service methods. For example, rather than calling a search() method on a remote service, you have a search object that gets sent to the server and the server returns the corresponding result or response object. By using this pattern, you can effectively implement caching, batching, undo/redo, etc. See Ray’s presentation for a bit more info on this.

One ready-made implementation of the pattern for GWT is the gwt-dispatch library. I considered integrating this into the Grails plugin, but its server-side components weren’t really suitable for a Grails project. Anyway, I wanted to write something myself so I could better understand what the implementation should do. The result is the plugin’s new action framework, which you can test out with an intermediate release of the plugin.

Getting started

Using the framework is simplicity itself. Let’s say you want to implement a search action. You first create the appropriate classes for it by running a new Grails command:

grails create-gwt-action org.example.myapp.Search
This will create the following files:

  • src/java/org/example/myapp/client/SearchAction.java
  • src/java/org/example/myapp/client/SearchResponse.java
  • grails-app/actionHandlers/org/example/myapp/SearchActionHandler.groovy

The action and response classes represent the request and response data respectively. Both of them implement Serializable, so they have to have a default constructor (which can be private) and can only contain other serializable data. Note that they are added to the client sub-package of the package you specify, because they are used on the client was well as the server.

The action handler is an instance of a Grails artifact type added by the plugin. Its role is to process actions and return the appropriate responses. It would typically offload the majority of the work to a standard Grails service that could then be used by other code, such as a REST or web services interface.

The code

Update I have updated the plugin packages in the following examples, so “org.grails.” is now just “grails.” The change was made for the final release of version 0.5.

The action object should contain only the information necessary to complete the request. Remember, it’s a data object and typically won’t have any behaviour. In the case of our search action, we might need a query string and the maximum number of results the search should return:

package org.example.myapp.client;

import grails.plugins.gwt.client.Action;

public final class SearchAction implements Action<SearchResponse> {
    private static final long serialVersionUID = 1L;

    private String query;
    
    private SearchAction() {}
    
    public SearchAction(String query) {
        this.query = query;
    }

    public String getQuery() {
        return query;
    }
}

Likewise, the response should only contain the data required by the client:

package org.example.myapp.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import grails.plugins.gwt.client.Response;
    
public class SearchResponse implements Response {
    private static final long serialVersionUID = 1L;
    
    private ArrayList<Long> ids = new ArrayList<Long>();
    
    private SearchResponse() {} 
        
    public SearchResponse(List<Long> ids) {
        this.ids.addAll(ids);
    }
        
    public List<Integer> getIds() {
        return Collections.unmodifiableList(this.ids);
    }
}

All very straightforward so far. The final step is to implement the action handler. As I said, this typically offloads the work to a service and in our example we will make use of a search service:

package org.example.myapp

import org.example.myapp.client.SearchAction
import org.example.myapp.client.SearchResults

class SearchActionHandler {
    SearchService searchService

    SearchResponse execute(SearchAction action) {
        def results = searchService.executeSearch(action.query)
        return new SearchResponse(results)
    }
}   

As you can see, all the action needs to do is unwrap the action and create the response. Everything else is handled by the search service. We haven’t even needed to expose a service via GWT! That’s all you need to do on the server side, which just leaves the question of how you execute an action from the client.

On the client

The plugin comes with a dedicated GWT RPC service that you can use to dispatch all your actions: GwtActionService. All you have to do in your GWT code is create the service, instantiate your action, and then call the execute() method:

...
import grails.plugins.gwt.client.GwtActionService;
import grails.plugins.gwt.client.GwtActionServiceAsync;
...
protected void doSearch(String query) {
    GwtActionServiceAsync service = GWT.create(GwtActionService.class);
    ((ServiceDefTarget) service).setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");

    service.execute(new SearchAction(query), new AsyncCallback<SearchResponse>() {
        public void onFailure (Throwable caught) {
            ...
        }

        public void onSuccess (GetRecentResponse result) {
            ...
        }
    });
}

You could even wrap the action service with another implementation that does caching and/or batching of commands.

If you use Google Gin, you can simplify your code by having the action service injected into the classes that need it. Simply add something like this to your Gin module definition:

...
import grails.plugins.gwt.client.GwtActionService;
import grails.plugins.gwt.client.GwtActionServiceAsync;

public class MainModule extends AbstractGinModule {
    protected void configure() {
        ...
    }

    @Provides @Singleton
    GwtActionServiceAsync provideGwtActionService() {
      GwtActionServiceAsync service = GWT.create(GwtActionService.class);
      ((ServiceDefTarget) service).setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");
      return service;   
    }
}

Since GwtActionService is provided by the plugin, you also need to configure your module to inherit from the plugin’s (new) module:

<module>
    ...
    <inherits name="grails.plugins.gwt.Grails"/>
    ...
</module>

I think this is a really clean approach to GWT RPC that reduces the burden on you as a developer. In particular, you no longer have to implement GWT services because you can create simple action handlers instead. Before I implemented this framework, I found that I was creating specific GWT versions of each service. So for example, I had a SearchService and a GwtSearchService, which was pretty inefficient.

I hope you like the new approach!

Internationalising your Grails + GWT applications

The recent 0.4 release of the Grails GWT plugin includes some enhancements in the area of internationalisation (i18n), so now seems like a good time to have a look at how you can add i18n to a Grails/GWT app. This article focuses on the specifics of getting GWT’s i18n support working with Grails, but the GWT website has a useful tutorial if you want more information.

Localising text

Grails and GWT take different approaches to i18n. Both systems are based on properties files with names that follow the usual Java i18n convention for resource bundles, but that’s as far as the similarities go. Grails expects to find the bundles in the grails-app/i18n directory, but GWT looks for them in the module directory structure. With static internationalisation, GWT also requires each property file to have an associated Java interface.

Ideally, you would be able to use the same properties files for both standard GSP pages and GWT code, but the plugin doesn’t support this yet. I don’t even know if it’s possible. Despite that, the plugin does make it easy to get started. Let’s say you have a GWT module org.example.Main that you want to internationalise. The first step is to create the resource bundles that will contain the localised text:

grails create-gwt-i18n org.example.Main
This simple command will generate two files for you:

  • src/gwt/org/example/client/MainConstants.properties
  • src/gwt/org/example/client/MainMessages.properties

The MainConstants.properties file is for basic localised text, whereas MainMessages.properties contains parameterised messages like “Today is {0,date,medium}” (where {0…} is a message parameter). Other than that, both properties files can be treated as standard Java resource bundles.

So how do you access these messages from your GWT code? By creating Java interfaces based on the entries in the properties files and loading the appropriate implementations for those interfaces using GWT’s deferred binding mechanism. It sounds complicated, but in practice it’s pretty straightforward. The plugin provides a Grails command that will perform the first step of creating the appropriate Java interfaces:

grails compile-i18n
Assuming that you have added some enties to the MainConstants.properties and MainMessages.properties files, this command will create

  • src/gwt/org/example/client/MainConstants.java
  • src/gwt/org/example/client/MainMessages.java

In fact, you don’t even need to run this command explicitly because the plugin will run it automatically before compiling the GWT modules.

Both the *Constants and *Messages interfaces contain methods named after the keys in the corresponding properties files. For example, an entry cancelLabel will result in a method cancelLabel(). In the Java world, developers commonly use ‘.’ as a separator in resource bundle keys. You can do this with GWT too, but you end up with underscores in the method names. For example, cancel.label becomes cancel_label(). In other words, the generated methods don’t follow the Java convention. Whether that’s an issue is really down to you.

Now that you have the i18n interfaces, you can start replacing hard-coded text in your GWT UI with localised text. You first need to load the appropriate i18n classes:

public class Main implements EntryPoint {    
    private MainConstants constants = GWT.create(MainConstants.class);
    private MainMessages messages = GWT.create(MainMessages.class);
    ...

You can now call the methods on the constants and messages objects to get the localised text:

public class Main implements EntryPoint {
        ...
        Button saveButton = new Button(constants.save_label());
        Button saveButton = new Button(constants.cancel_label());
        ...
        // Report an error
        RootPanel.get("errorMessage").add(new HTML(messages.msg_upload_fail(filename)));
}

You can also see in the above example how you pass parameters to a message as simple method arguments.

Adding locales

That’s almost all there is to it. Your application will now work with the default locale. To add extra locales, though, requires a few more steps. First off, you need to create the language-specific resource bundles with the translated text. Say we want to display the application in French. We create the files

  • src/gwt/org/example/client/MainConstants_fr.properties
  • src/gwt/org/example/client/MainMessages_fr.properties

and add the French versions of all the messages there. Next, we need to inform GWT of the new locale by adding the following line to the module file:

<module>
    ...
    <!-- Supported languages -->
    <extend-property name="locale" values="fr"/>
</module>

That’s it! Your users can now view the application in French.

Setting the locale

The application is now localised, but how do you pick which locale to display? The simplest approach is to add a “locale=…” query parameter to the application’s URL. GWT picks up that parameter and loads the appropriate resource bundles. Unfortunately, this doesn’t work so well with Grails because it uses a different query parameter: “lang=…”.

Another issue is that you have to add the “locale” query parameter to any internal links so that the correct locale is propagated to the different pages. This is a pretty ugly and error-prone approach.

Have no fear! There is a simple solution. Simply add the following meta tag either to your GSP pages or, even better, your layouts:

<%@ page import="org.springframework.web.servlet.support.RequestContextUtils" %>
<html>
<head>
    ...
    <meta name="gwt:property" content="locale=${RequestContextUtils.getLocale(request)}">
</head>
...
</html>

Not only will this ensure that GWT uses the same locale as Grails, but the locale will also be retained between pages and modules. To change the locale to French, all you have to do is load the application with the query parameter “lang=fr”. Next time you reload the page without the query parameter, it will still be in French! The same when you navigate to a different URL with the application. Now that’s what I call a result.

Have fun internationalising your Grails/GWT apps!

GWT Plugin for Grails 0.4-SNAPSHOT

I have just released a new interim version of the GWT plugin for Grails. The main changes are:

  • it works with GWT 1.6 properly
  • GWT client requests now go through a controller
  • new command: clean-gwt-modules

Two of those are pretty self-explanatory, but the second one deserves a closer look.

In the beginning…

The traditional approach to GWT RPC involves creating a servlet that extends GWT’s RemoteServiceServlet class for each remote service in your application. Prior to version 0.4, the plugin used a technique based on that approach but geared towards Grails. Rather than requiring the user to create his own servlets and configure them in the web descriptor, the plugin set up a single servlet (extending RemoteServiceServlet) for each GWT module. The servlets simply forwarded requests to the appropriate Grails service.

This approach worked well, particularly as the user gained all the benefits of using proper Grails services, but it meant that neither URL mappings nor Grails filters took effect. Each module had to send requests to a hard-coded URL: /gwt/<moduleName>/rpc. With the introduction of version 0.4 of the plugin, this has all changed.

Enter GwtController

The custom GWT servlet has gone, disappeared, vanished. In its place you’ll find a new controller: GwtController. It works in a similar way to the old servlet, but because requests now go through the standard Grails dispatch logic, URL mappings and Grails filters can now be used on GWT requests.

You don’t have to do anything special to get the new version of the plugin working with your application because it comes with a URL mapping that matches the old hard-coded URL:

class GwtUrlMappings {
    static mappings = {
        "/gwt/$module/rpc"(controller: "gwt", action: "index")
    }
}

Note that the above mapping includes a module parameter, but the controller currently doesn’t use it any way. It’s only there so that the mapping behaves the same as the old servlet URLs.

If you want to send GWT requests to a different URL, simply add a new entry to your application’s URL mappings. You will need to map the URL to the same controller and action as shown in the code above.

That’s all there is to it! Please try it out and let me know of any problems.