For those of you who don’t know what OpenID is, get to know it now. This post is going to be about how to use OpenID authentication in your GWT applications.
First, a reminder of what OpenID is:
OpenID is a free and easy way to use a single digital identity across the Internet.
My point of view is that OpenID allows site developers not to worry about expensive authentication processes while giving its users the comfort of trusting one supplier of authentication to keep their password and other identification means safe from the bad guys out there. For example, by using OpenID your users who have signed up to Verisign’s PIP can use their keyring dongle to log in to your site, without writing a single line of code specific to keyrings at all.
Design considerations
While OpenID has great library support in most web development languages including Java, it seemed to me that GWT required a bit of tweaking in order to get it to work:
- The HttpServletResponse object received by the GWT servlet RemoteServiceServlet does not allow redirections.
- GWT’s concept is that there are no long-term sessions. The HttpServletRequest.getSession() method returns a local session object, and data cannot be stored there, so information regarding the OpenID authentication process needed to be stored somewhere else.
In addition, I wanted the resulting classes dealing with the OpenID authentication to be reusable, unit-tested, and decoupled from the method used to store the authentication process information. In order to achieve the decoupling, I’ve created a callback interface which the application holding the storage space implements. The reusability is achieved thanks to this decoupling, and by making it a standard HttpServlet (more on that later): the class only contains OpenID authentication logic, and no application logic. Unit-testing the class was trickier, since the class was a servlet and required an HTTP conversation to take place for it to be tested. However, that was achieved using the Cactus framework (that too required a few tricks.. But that story is for a different post!)
Implementation
At first, I’ve decided on the basic interface the GWT service should have:
public interface UserAuthentication extends RemoteService {
LoginResult login(String openIdURL);
UserDetails getCurrentUser();
void logout();
}
After that, I’ve made the sequence diagram which covers what happens behind the scenes:
The implementation code can be found here. There are a few things worth noting about the it:
- The login method does not return the user details. Instead, it either returns that the user was successfully logged in or that it was not, and attaches a URL. The client then redirects itself to that URL. Note this simple JSNI code for client-based redirection.
- The first URL the client receives (the one mentioned in the last point) is actually a URL still within the web application; the only difference is that it is not a GWT servlet. This is a big difference, as it allows implementing the doGet method and allows for real redirection, using the HttpServletResponse.sendRedirect method.
- Apparently, GWT supports having servlets of all kinds, including ones that are not GWT servlets. This is how the OpenID servlet is added: just as a normal tag: <servlet path=”/openid” class=”my.pkg.OpenIDServlet” />.
- The first cookie the client receives, the “unique ID” cookie, is what will identify the client when he gets back from the OpenID provider. This is saved to some shared record available to all web servers running the application, containing this unique ID and, if the client returns with a successful log in credentials from his OpenID provider, the client’s OpenID user URL as well.
- The callback implementation is supposed to save the information on some storage. In my application, I used Hibernate to store a small class containing a random UUID (the unique ID sent on the first cookie) and the OpenID user URL. I then used Hibernate again to create a join between this record and my user details record, which contained application specific data. That way, even the storage solution I chose was decoupled from my application.
- Instantiating the callback was a task handed to a dependency injection mechanism, as I didn’t want my application code to deal with that. The mechanism I chose to use was Google’s Guice.
- I chose to use OpenID4Java as the OpenID implementation. Afterwards, I noticed that Verisign had their own implementation, JOID, which keeps its own data store, ridding the need to do it yourself. I didn’t try it though, so I can’t say whether it works as a “drop-in” library to my implementation of the servlet, or whether its easier to use.
As always, I’m looking forward to your comments!


April 26th, 2008 at 8:23 pm
Thanks a lot for this post!!
April 26th, 2008 at 8:45 pm
You’re welcome Severus! Thanks for the comment!
June 18th, 2008 at 2:11 am
hi aviad,
thanks for sharing. good stuff.
by the way, are you able to debug openid within gwt via the gwt hosted mode? the redirects are causing some problems for me.
June 18th, 2008 at 3:58 pm
Hi foo!
Unfortunately, I haven’t been really able to “debug” openid - I send the redirect, and pray.
More sersiouly, openid4java is open-source and therefore you can debug it. I had some problems there because the source provided wasn’t matching the binaries.. But it was enough to understand the reason for the error in most cases. Did you try that?