Tag Archives: OpenID

Yahoo! OpenID’s XRDS check, Apache2 and PHP

Another continuation of a previous blogging session :-)

A reminder, we’re talking about this:

Warning: This website has not confirmed its identity with Yahoo! and might be fraudulent. Do not share any personal information with this website unless you are certain it is legitimate.

PHP+Apache2 users out there might be interested in this reminder, which it’s already mentioned on previous post’s checklist, but I’d like to point it out again.

Don’t name your file xrds.xml.php and try to serve it as xrds.xml while changing Content-type to application/xrds+xml in the header. Apache2 is braindead (or used to be) and doesn’t even attempt to execute the file.

Yahoo! sends an Accept header in its HTTP request, listing application/xrds+xml. Apache decides your file is not of correct filetype, and sends Yahoo! the 406 Not Acceptable response. Referring to same file with the .php extension included makes Apache actually execute the file, and then compare the content-type to the accept header from the client.

Yahoo! and OpenID verification

Seen this in your OpenID consumer implementation when logging on to Yahoo?

Warning: This website has not confirmed its identity with Yahoo! and might be fraudulent. Do not share any personal information with this website unless you are certain it is legitimate.

Over there at http://zatemas.zrs.hr/ we’ve had this for quite some time now. How we eradicated it? Here’s a few pointers. I’m not sure what exactly helped.

  • More a generic tip than anything else: even Yahoo! crew recommends reading this blog post.
  • We had a redirect from our root page / to /run.php?app=news. We eliminated it through some trickery (setting $_GET and including run.php … sick but works)
  • Yahoo! discovers your XRDS document primarily through headers, just as aforementioned blog post says.
    • So on your realm page send header X-XRDS-Location pointing to your XRDS document.
    • And also include meta tags. ZATEMAS even added special kind of plugins so it can more easily send the special meta tag.
    • By the way, in janrain’s php-openid library’s openid consumer samples, the ‘realm’ is generated by getTrustRoot()
  • XRDS document should contain a pointer to your return-to page. (That’s the whole point.)
    • To stay on the safe side, I also added the aforementioned X-XRDS-Location header and meta tag into our openid_finish.php page.
  • Your XRDS document should return content-type application/xrds+xml
    • Apache looks braindead here. While it’ll happily serve our xrds.xml.php under xrds.xml, it’ll also happily refuse to serve it in case it gets “Accept: application/xrds+xml”, like Yahoo! does, resulting in 406
    • Yes, even with header(‘Content-type: application/xrds+xml’);
    • Point is: don’t avoid .php extension. All works if request goes to /xrds.xml.php instead of /xrds.xml — and you won’t see the problem or difference with regular browser. Only hint is when you open access logs and you see non-browser requests for your file ending up in 406.
  • Your realm page must not redirect.
    • Your realm page, your trust root. In ZATEMAS we use http://zatemas.zrs.hr/ – this means both production and SVN version (in subfolder /SVN) can consume same OpenIDs. Otherwise our users would get different OpenIDs from at least Google.
    • I’m not sure if it makes a difference to Yahoo!, but remember that forgetting slash in directory URLs means Apache performs a redirect. 
  • Again, don’t mess up: if you change filename, make sure you change both X-XRDS-Location header and meta tag.
  • Again, don’t forget: Apache won’t even open your PHP-generated XRDS document if only application/xrds+xml is accepted by the client, and you try to feed it by stripping PHP extension. Just keep the darned extension and serve it to the OpenID provider.

Hope my experiences help someone because this evening we finally got rid of Yahoo!’s warning.

One last note: if you’re a foreign visitor to ZATEMAS and you can’t speak Croatian, you can pass GET argument lang=en to make use of our automated Google-Translate-leeching string translation service. This only works in development version (subdirectory /SVN) because translation module is disabled on production site — it eats away too much page generation time :)

EDITED: This is value of Yahoo’s XRDS verifier Accept header: application/xrds+xml,text/html,text/plain