Tag: basic authentication
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:
- GWT & Spring
- anonymous usage till authentication is required
- 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.