Boulevard of Broken Builds

Add authentication to your GWT application

by Roald on Aug.17, 2009, under Uncategorized

I’ve been looking around for ways to add security to our GWT frontend. It seems that most solutions dictate a form post. One way to do this, is at the start of the application. But as one of our requirements is partially anonymous usage, this wasn’t the way I wanted to go.

My goals:

  1. GWT & Spring
  2. anonymous usage till authentication is required
  3. Secure, but don’t over do it

A quick google made me look at the gwt-incubator-lib project. It’s a small project by David Martin build on GWT-SL. It basically extends org.gwtwidgets.server.spring.GWTHandler to create a custom error handler.
Unfortunately, it also mandates checked security exceptions to be thrown by every service method you want to secure. This is rather intrusive to your code, so I started to look for another way.

I took David Martin’s approach of extending GWT-SL and changed the org.gwtwidgets.server.spring.GWTRPCServiceExporter. In the doUnexpectedFailure method, I added specific Spring-Security exceptions to be handled. As I am a bit of a REST-fan I tried to set the response code according to the error at hand. Therefore, I mapped the spring security exceptions like AccessDeniedException to return a normal GWT body with status code ‘UNAUTHORIZED‘ or ‘401‘. This makes error handling at the client side very easy as you can check the status code of the response without any difficulty.

Next step is making authentication possible when needed. I came across an undocumented feature of GWT, which helpes a great deal. You can let your async service return a RequestBuilder object. As a consequence the request is not send on method call, but you get the requestBuilder instance to send it yourself. Not only does this gives you the ability of changing the request right before sending it. You also have a hook to perform a resend.

Putting it all together in a structured way, I can now call secure method from my controller:

authenticationManager.doSecureRequest(
      productRemoteService.getProducts(new AsyncCallback<List<Product>>() {
   public void onSuccess(List<Product> value) {...}
   public void onFailure(Throwable caught) {
      // default error handling
   }
}));

Here is the only intrusive code you’ll find. Even the LoginDialog is hidden from your code. The AuthenticationManager takes the RequestBuilder returned from your service method and does a little magic. First it takes the default callback method from the requestbuilder and overwrites it with a new one, which can handle security exceptions. It then tries the requested service method and checks the response status code. If the request code is OK, we can return to our original callback. Otherwise, when it’s an security exception, we can popup a login dialog and use the credentials in a retry of the same request. This behavior can be extended to handle any status code that is required.

Passing along the credentials to the server is an issue on itself. Most of the time, you’ll find that clear text is send over the wire. As I wanted a little bit more security, I implemented basic authentication within my AuthenticationManager. This way, when the application is deployed on a TLS enabled webserver (and is accessed through TLS), the communication is relative secure. Of course you can continue along this line and implement digest is the same manner. Adding the credentials to the request is done through a header field.
   requestBuilder.setHeader("Authorization",
      "Basic " + base64Encode(username + ":" + password));

I let the authenticationManager keep track of the header value, so I can add it with following requests without having to ask the user the credentials for every service method that needs authentication.

Concluding, I think this shows a relative clean implementation of GWT security. The only intrusion happens on method call, which makes it easy, although not recommended, to implement security after the fact.




1 Comment :, , more...

Google Web Tookit 1.6

by Roald on May.29, 2009, under Uncategorized

Today I took a first look at upgrading our application from 1.5 to GWT 1.6.
I was stunned to find the changes Google made in the basic structure of GWT. And much more about the lack of support.
Apperantly the ppl at Google think there is only one IDE and only one build system. Or at least that every should conform themselves to Google’s policy.
I guess I have to spend some time again digging into the compiler options to create a new version of the mvn-gwt-plugin. I’ll keep you posted on the progress.

Leave a Comment : more...

Google Web Toolkit

by on Sep.27, 2008, under Uncategorized

Last monday the book I wrote together with Bram and Uri (Beginning Google Web Toolkit) was released by Apress. It was half a year of work and it took quite a bit more effort then I originally expected, but I’m more then satisfied with the result.

In light of the release of the book, I’ve also decided to put the maven plugin I’ve developed up for public usage. As of yesterday it’s available under net.bankras:mvg-gwt-plugin. You can use it to compile your GWT code into a war archive, or start a hosted mode environment from a console. There are a lot of default configuration values, with overwrite options. Below you can find an easy configuration which will suffice for most situations.

<build>
    <plugins>
        <plugin>
            <groupId>net.bankras</groupId>
            <artifactId>mvn-gwt-plugin</artifactId>
            <version>1.0.4</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Leave a Comment more...

Core Web Services by SpringSource

by on Nov.28, 2007, under Uncategorized

The last two day I’ve spend following the first world wide SpringSource Core Web Services course. Arjen Poutsma and Joris Kuipers formed a close team delivering more than Spring from the Source :-) . Although up front I was expecting a real hardcore course covering all aspects of webservices and spring-ws in specific. Especially as Arjen was the the primary trainer of the course this would be hard-hard-hard-core. After the first day though, coffering only xml namespace and xpath, soap and wsdl, I wasn’t too optimistic about the core aspect of the course. In particular comparing to the stories I’ve heard about the spring-core training.

The second day however, although only covering extensive spring-ws, ws-security and rest, gave me the feeling that all the core issues had been covered. I could not think about any particular subject which some absolutely needed to know about, to mangle him/her-self into any webservice topic. Which does not mean some topics remain unanswered. Arjen and Joris gave the group a real democratic vote on the topic of the second day, which excluded ws-addressing and a architectural SOA discussion (which might have been the most interesting!). However I might feel about the outcome of the vote, the course itself was of a high level. Especially for a first offering.

Besides the topics mentioned above the topic about ws-versioning remains a hot topic for me. And I definitely won’t spend another opportunity to discuss this topic with Arjen, as I’m very curious about his opinion besides using the transformation filter.

But generally a have a positive feeling about the course. And I would definitely recommend using spring-ws in any project requiring a webservice implementation.

Leave a Comment more...

EnhancerByCGLIB and equals()

by on Oct.16, 2007, under Uncategorized

Suppose you have a simple pojo class called MyPojo. Containing some arbitrary attributes and an id and version. The by IntelliJ generated equals() method for this object will look as follows.

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass())
            return false;
        RecordImpl record = (RecordImpl) o;
        if (version != record.version) return false;
        if (id != null ? !id.equals(record.id) : record.id != null)
            return false;
        return true;
    }


Suppose now we use Hibernate to persist this object and there are two related object through which we retrieve two lazy instances of this object. The nature of Hibernate will now enforce both instances to be bytecode enhanced by cglib, which results in two instances of the class MyPojo$$EnhancerByCGLIB$$.
So what happens now if we call equals on those instances (let’s call them p1 and p2). So p1.equals(p2) results in the following execution lines.

  1. if (this == o) return true;
  2. Which is false, so we go on

  3. if (o == null || getClass() != o.getClass())
  4. Here we run into a problem. The class of o is MyPojo$$EnhancerByCGLIB$$ which does not equals the class of this, i.e.MyPojo. So what we need to do to fix this is to compare the class of p2 through different means

  5. if (o == null || !(o instanceof MyPojo))
  6. MyPojo pojo = (MyPojo) o;
  7. if (version != pojo.version) return false;
  8. Ouch. Hold on. Calling the version attribute will give an exception. Remember that the class is cglib enhanced. So the properties still have to be retrieved. We have to use the get method.

  9. if (version != pojo.getVersion()) return false;
  10. if (id != null ? !id.equals(pojo.id) : pojo.id != null)
  11. Again. We have to use the getter.

  12. if (id != null ? !id.equals(pojo.getId()) : pojo.getId() != null)
  13. return true;
  14. And finally we know they are equal.
    I wish this would be it. However, if MyPojo would have an interface in front of, the next problem comes around. CGLib will enhance the interface instead of the implementation. As a concequence the instance can no longer be casted to the implementing class. Hence, line 3 will give a ClassCastException. We have to adjust it to work with the interface. Fortunately we no longer use direct property access, so this won’t be a problem.

  15. MyPojo pojo = (MyPojo) o;

So now we have a equals which should evaluate correctly two instances. But I don’t like it. Making the equals method dependent on a implementing interface restricts me from implementing multiple interfaces. Or else I would have make the equals method more complex. If anyone has a better sollution, please let me know.

Leave a Comment more...

GWT shortcomings

by on Sep.28, 2007, under Uncategorized

Today I ran into a surprising shortcoming of the Google Web Toolkit. For a particular project, the client had requested a link to an external page to be added to a panel. However, browsing through the GWT javadoc, I wasn’t able to find a widget which would make this possible. It seems that Google forces you to use either a HTML widget which prevents you from any validation or use the DOM object, which is rather cumbersome. Fortunately, a collegue of mine already encountered the same problem in a different project and had created his own widget for this purpose. By adopting his code, my problem was easily solved.

Leave a Comment more...

The second JTeam-author

by on Aug.31, 2007, under Uncategorized

As Bram has proudly announced on his blog, a new book has been published about developing enterprise applications with Spring. I’ve started reading and I will share my first impressions here asap.

Leave a Comment more...

Your favorite workspace

by on Aug.04, 2006, under Uncategorized

Joel Spolsky wrote another story on their workspace. In a previous post he wrote about the design of their new office. Apparently they came up with a lot of specs for a developers office. In this post he ones more stresses the importance of privacy for developers. It strikes me as a real cultural difference between Europe and America. All the companies I’ve seen here, the offices are open spaces. However, I do have to agree that my concentration gets lost as soon as two other colleagues start arguing again. So my favor definitely lies with the American system.

Leave a Comment more...

Extending org.hibernate.Dialect

by on Jul.21, 2006, under Uncategorized

Today I ran into the problem that hibernate does not support all SQL functions some databases might support. Although the solution wasn’t hard to find, it wasn’t the way I would have come up with. Apparently Hibernate does not want to support everything in their dialects. Even though they are database specific. So the easiest way to solve my problem was to extend the dialect I was using.


class HibernateMySqlDialect extends MySQLInnoDBDialect  {
    public HibernateMySqlDialect() {
        registerFunction("date_add_interval",
                new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));

        registerFunction("date_format",
                new SQLFunctionTemplate(Hibernate.DATE, "date_format(?1, ?2)"));
    }
}

That’s all what’s necessary to start using these SQL functions in your HQL queries.

Leave a Comment more...

lntelliJ Idea live templates for maven plugin development

by Roald on May.18, 2006, under Uncategorized

When writing your a maven plugin in Idea, one immediately notice the lack of tag support. So I’ve created some live templates, to support just that. If you want to use them, do as you wish. However, I just made this in five minutes, so I’m not taking any responsibilities for it. If you have some comments/suggestions/improvements, do let me know.

Here is how you can install it.

  1. Download this file, and place it in $USER_HOME/.IntelliJIdea/config/templates
  2. (re)startup IntelliJ (templates are loaded on startup)
  3. add the following list to Settings -> IDE -> Errors -> General -> Unknown javadoc tags -> Additional javadoc tags
    • aggregator, execute, goal, phase, requiresDirectInvocation, requiresProject, requiresReports, requiresOnline, parameter, component, required, readonly

Enjoy!!

Leave a Comment more...

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!

Visit our friends!

A few highly recommended friends...