Thursday, June 5, 2008

OpenID and Entity Describer

So in the last week, I've gone about the task of setting up and testing openID to for the next Entity Describer minus Connotea. Fortunately there was a lot of forum posts and advice on the web on how to get OpenID set up for a website.

A good overview of it is: A recipe for enabling OpenID on your site
Since Entity Describer is programmed using Java Servlets, I used the OpenID4Java library. This one in particular because it specifically state version 2.0 which is what most OpenID Providers conform to now. However, for other programming languages a complete list of libraries may be found here.

After installing the libraries, the rest was implementing the servlet to handle the openID login. I've saved it under the ED project as package org.icapture.ED.openID as OpenIDHandler.java. Most of the example code I was following came from the library I downloaded from OpenID4Java. Particularly under the INSTALL file and the ConsumerServlet.java in the examples folder.

The workflow for OpenID goes as such:
-User requests the OpenIDHandler Servlet and a ConsumerManager object is instantiated. The ConsumerManager is the main OpenID object which handles most of the communication between ED and the OpenIDProvider(OP).

-The user submits an openID URL eg. (http://example.myopenid.com)

-Our website (also referred to as a Relying party or Consumer) extracts from that who the OpenID Provider (OP) is and does a discovery on them to make sure they exist. This is done by calling the discover function of the ConsumerManager.

-Once our website knows the OP exists it forms an AuthRequest message to request Authorization from the OpenID Provider. This is done by calling the ConsumerManager's authenticate function. This will cause the OP to do a GET on the returnToURL you passed into the authenticate function. With ED I gave it the OpenIDHandler's URL with the parameter "?return=1". Bare with me, this is where it gets interesting because I'm going to start talking about XRDS documents and YADIS protocol

-When the OP is doing a GET on the returnToURL, it is expecting to get an XRDS document from it. What's an XRDS document? it stands for
eXtensible Resource DescriptorS. It's also known as a Yadis Resource Descriptor. In it I've specified the returnToURLs OpenID may return to after it's done authenticating (I just tell it to go back to the OpenIDHandler servlet). It's used to let the OpenID Provider know that the returnToURLs are using openID.

-There are a few different ways of giving the xrds document. But according to the Yadis Protocol you should do this by adding the header "X-XRDS-Location" to the response with the value being the URL where your xrds document is located.

response.addHeader("X-XRDS-Location", xrdf_path);

In ED I've named the document: Yadis_xrds_doc.xrdf in /WebRoot/ed. I've also added the mime type for .xrdf extension under the web.xml



xrdf
application/xrds+xml


-*Please note if you put a breakpoint during this GET. It will cause the authentication to fail.

-After all that the OP has now verified that you're OpenID enabled and you've got an AuthRequest object. What to do next? That depends on the version of OpenID the OP is using. Usually it's version 2.0, but ED handles both version just in case. If the OP's version 1.0, just redirect to the OP's URL that's responsible for handling authentication (also referred to as OPEndpoint) like so...

response.sendRedirect(authReq.getDestinationUrl(true));

If it's version 2.0 then it's a little more complicated. Basically what happens is you add 2 attributes to the HTTPrequest. One being the OPEndpoint and the other being the parameterMap you get from the AuthRequest. Then you forward the request and response to a dispatcher. A dispatcher being just another page that uses the same request and response and does the work. With openID version 2.0 the dispatcher MUST have a form with a sumbit button and the parameterMap is turned into inputs of type HIDDEN inside the form. The form posts to the OPEndpoint.

-The OP handles the authentication from here and returns control back to the URL designated as the return to URL. Here, ED verifies the Response from the OP by calling ConsumerManager.verify. This is to make sure it DID come from the OP we sent to. If it is verified, the user is authenticated and ED changes state to logged in.

Useful Links:
OpenID4Java JavaDocs

OpenID version2.0 Specs

Brief Description of what YADIS is

No comments: