Yesterday night i finished implementing openID with one of the web applications I am working on. In that case it was PHP based and using Zend_OpenID. At least I thought I finished it.
Today I was discovering that I missed an important part.
I guess it is because I was so happy that I finally got messages back from Google and claimID. But openID is a 4 step procedure, not a 3 step one:

  1. We take the user supplied openID url and validate that it matches one of our users.
  2. We request from that URL and get some HTML back where we need to discover the actual server back (Am I the only one finding this procedure hacky?)
  3. We redirect to the actual openID server, it will ask our user for login and redirect back.
  4. We get redirected back and get some information on the user. Take the openID url and are ready to go.
    What we are getting back is an HTTP-GET request made from an URL which we think comes from the openID provider. Actually the most important part of the openID authentication is to not trust this data. This could be faked by hackers, well actually even simple minded could do that :-) . So the last step is:
    Validate the received parameters against the same openID server.

The nasty thing is that you could think that after step 3  you are done. If you stop there you not just implemented openID, but login for everyone.

An interesting side note is that Yahoo! openID is broken at the moment. It returns on discovery via a valid openID:

<link rel="openid2.provider" href="https://open.login.yahooapis.com/openid/op/auth">
<link rel="openid.server" href="https://open.login.yahooapis.com/openid/op/1.1/auth">

Both actually are nonworking URLs. The first even states that Yahoo only supports the openID v2. Perhaps they should update then their discovery url so their service gets found?

Update:

Well actually Yahoo no longer uses HTML discovery, but they havent removed the discovery from the page. That was confusing me. Yahoo supports however now Yadis XRD based detection, which unfortunalty is not yet adressed in Zend Framework.