OpenID 2.0 and HTTP redirects

Ever since I signed up on StackOverflow.com roughly a year ago, I’ve had an OpenID. On the whole, I think it’s a great con­cept, and I wish more sites would allow me to sign in with it.

How­ever, a few things have been both­er­ing me about it.

When I first signed up, I did a bit of research, and found out that you can use your own domain as your OpenID. You sim­ply enter the fol­low­ing in a <head> of a HTML page you control:

<link rel="openid.server" href="http://myopenidprovider" />
<link rel="openid.delegate" href="http://myopenid-at-that-provider/" />

And the URI of that HTML page can now be used as your OpenID. It will for­ward authen­ti­ca­tion requests to the spec­i­fied provider. This gave me a nice clean URI to use as my OpenID, and as a bonus, it meant that I could change my OpenID provider and keep my ID, just by edit­ing this HTML.

Of course, I quickly found out there was a down­side as well. When I cre­ated this blog, I placed it in http://jalf.dk/blog. I fig­ured I could eas­ily add a redi­rect from http://jalf.dk and so it wouldn’t mat­ter in the long run.

When I tried adding this redi­rect, I real­ized that this of course would also redi­rect any OpenID requests. My OpenID provider would then see a login attempt from http://jalf.dk/blog instead, and all hell would break loose.

So I removed the redi­rect, and instead placed this mes­sage in http://jalf.dk/ along with the OpenID <link> tags:

Please go here for my blog. Sorry for the lack of a proper redirect.

Not very ele­gant, but it worked. OpenID requests were han­dled cor­rectly, and read­ers of my blog could fol­low the link, or just book­mark /blog in the first place.

Today, a friend asked me why I didn’t have a redi­rect, and I explained the above prob­lem. I didn’t think about it any fur­ther until half an hour ago, when I real­ized that Face­book can be tied to an OpenID account. As I said before, the more ser­vices I can log in to with my OpenID, the bet­ter, so I attempted to add my OpenID… And got a nasty error mes­sage telling me that my OpenID only sup­ported ver­sion 1.1, and Face­book required 2.0.

Geez, I hadn’t even real­ized there were mul­ti­ple versions.

So I went hunt­ing for a solu­tion. And it turned out to be pretty sim­ple, and have the nice side effect of solv­ing the redi­rec­tion prob­lem as well!

It turns out that the <link> tags embed­ded in HTML only work for OpenID 1.0 and 1.1. For 2.0, you have to pro­vide a YADIS XML file.

Unfor­tu­nately, there seems to be very few exam­ples online of what this file should look like. I did find a nice exam­ple of using a YADIS file for OpenID 1.0 here, which got me started. The Wikipedia arti­cle on YADIS held another exam­ple, but again only with OpenID 1.0. How­ever, it also shows how to spec­ify LID 2.0, so while I have no clue what LID is for, at least it gave a hint of how to sup­port mul­ti­ple versions.

Finally, div­ing into the spec­i­fi­ca­tion for OpenID 2.0, I dis­cov­ered the cor­rect URI to spec­ify as <Type> in the YADIS file: http://specs.openid.net/auth/2.0. Of course they just had to change the URI for­mat between ver­sions 1.1 and 2.0. Noth­ing is ever that easy.

But with this, the last piece fell into place. I cre­ated an openid.xml file look­ing like this:

< ?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"
xmlns:openid="http://openid.net/xmlns/1.0">
  <XRD>
    <Service priority="50">
      <Type>http://specs.openid.net/auth/2.0/signon</Type>
      <URI>http://myopenidprovider</URI>
      <openid:Delegate>http://myopenid-at-that-provider/</openid:Delegate>
    </Service>
    <Service priority="20">
      <Type>http://openid.net/signon/1.1</Type>
      <URI>http://myopenidprovider</URI>
      <openid:Delegate>http://myopenid-at-that-provider/</openid:Delegate>
    </Service>
    <Service priority="10">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://myopenidprovider</URI>
      <openid:Delegate>http://myopenid-at-that-provider/</openid:Delegate>
    </Service>
  </XRD>
</xrds:XRDS>

and using the PHP snip­pet from paulis­ageek,

< ?php
if (strpos($_SERVER['HTTP_ACCEPT'], "application/xrds+xml") !== FALSE) {
  header("Content-Type: application/xrds+xml");
  echo file_get_contents("openid.xml");
}
else {
  header("Location: http://jalf.dk/blog");
}
?>

I now have:

  • The same nice, short, easy-to-remember OpenID URI I always had
  • My blog acces­si­ble form http://jalf.dk
  • My Face­book account linked to my OpenID
  • Sup­port for OpenID ver­sion 2.0

All in all, I’m happy. And now that I’ve doc­u­mented the process, per­haps the next per­son who runs into this prob­lem may be a bit hap­pier too.

Share and Enjoy: These icons link to social book­mark­ing sites where read­ers can share and dis­cover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
  • Reddit
  • Technorati

Tags: , ,

Leave a Reply

Name and Email Address are required fields. Your email will not be published or shared with third parties.