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?
September 23rd, 2008 at 4:10 pm
i am make project using openid. are you send for me document openid4java ?
thank verry much
September 23rd, 2008 at 4:17 pm
i am student. i make project use openid. are you can send for me document openid4java ? thanks
October 4th, 2008 at 10:38 am
@tuan/commando (suppose you’re the same person): I don’t understand the request. In any case, openid4java is not a project I maintain nor contribute to – I just used it with GWT, and wrote about the experience.
January 23rd, 2009 at 10:11 pm
Hey Aviad:
Thanks for this writeup. Where is the code for:
import util.HttpCookies;
import util.DependencyInjection;
Thanks,
Richard.
January 24th, 2009 at 10:01 am
@Richard: Did you look in the libraries I referenced to in my implementation notes’ section? These should be found there.
January 26th, 2009 at 2:44 pm
Hey Aviad:
I cannot find code for the following:
import util.HttpCookies;
import util.DependencyInjection;
Thanks,
Richard.
January 29th, 2009 at 7:54 am
@Richard:
I didn’t have the space to include the code for everything. Both classes are just placeholders I used in the code I published, since they do something “simple”:
HttpCookies is a utility class which gets, sets and resets cookies on the user’s session. It works with the HttpServletRequest.getCookies and HttpServletResponse.addCookie methods.
DependencyInjection is a utility class which eventually works with Guice – see my comments on the implementation’s detail regarding dependency injection.
February 6th, 2009 at 11:56 am
hi,
I’m trying to implement OpenID in our gwt application using Eclipse IDE.
Is it possible to implement it in hosted Mode?
I cant get clear idea abt this implementation…..
I need ur help …..
i have lot of doubts.
if possible mail me @
inform.mail.kk@gmail.com.
February 11th, 2009 at 3:23 pm
Hi Aviad,
Help me ASAP.
Its urgent for our project..
Thanks in Advance.
Karthik
February 11th, 2009 at 10:40 pm
@karthik: Sorry for the delay. Yes, it can be done in hosted mode, however note that the servlet does require you to play a bit with the host – notice notes 3 and 4 in my implementation notes.
February 12th, 2009 at 11:58 am
Hi,
Thanks for your reply.
I got all your Code for Implementing OpenID , but i couldn’t find the 2 classes
util.HttpCookies & util.DependencyInjection.
I have a bit confusion in developing the codes for these classes.
So I need your help aviad.
If possible send the above mentioned classes to my mail…..
Hope u will Help me to solve this issue…
As we are currently doing openID I’ll be thankful if you send the code ASAP.
Karthik
February 20th, 2009 at 3:27 pm
Hi Aviad,
We waiting for your reply..
Its very urgent requirement for our project.
Help me ASAP.
Karthik
June 29th, 2009 at 4:37 am
can you provide a demo workable example on this? preferable spring as injection
June 29th, 2009 at 6:16 am
@asianCool: I already did provide a working demo. It lacks two classes that you need to implement (I explain how on the post). If you have any problem with the implementation, let me know.
June 29th, 2009 at 3:40 pm
can you show demo how gwt client call the servlet? is there a required to create composite “form” and do post?
July 2nd, 2009 at 3:46 pm
in the gwt client code, when seCookie and doGet to call the servlet, may i know what values you set for
“app-openid-auth”;
“app-openid-name”;
“app-openid-identifier”
“app-openid-uniqueid”;
July 3rd, 2009 at 6:18 pm
i know how to use the servlet already. i able to login using yahoo openid and myopenid.com , but cannot for google i enter url like below
http://localhost:8888/openid?app-openid-auth=true&app-openid-name=user@gmail.com
and get exception 0xa00: Authentication cannot continue: no discovery information provided.
July 3rd, 2009 at 8:59 pm
@asianCool: I’m sorry, but I’m not sure about specific OpenID providers. It sounds to me like the gmail.com domain did not return any discovered OpenID services, i.e. they don’t support OpenID. It sounds likely, too.
You might want to try http://openid-provider.appspot.com/ for Google accounts support, but I haven’t tried it myself.
July 3rd, 2009 at 9:00 pm
Or even better, try this: http://code.google.com/apis/accounts/docs/OpenID.html