After giving up for a while I revisited this issue and managed to solve it. Answering here in case anyone else faces the same issues. Ultimately it was down to my use of secure URLs.
TL;DR
It should have been the first thing I checked but, make sure you have an SSL certificate on your server so that the OpenID server is accessible via a secure URL. You will get a HTTP 500
error from GAE if the URL is not secure or if the SSL certificate does not validate (Obvious in hindsight but, this caught me out on a different test site with a custom generated SSL certificate).
In addition, make sure that the XRDS document contains said secure address in the <URI>
element.
Setup Details
- Using OpenID plugin Version 3.3.4
- Using XRDS-Simple plugin Version 1.1
- Wordpress version 3.8
- Hosted on WPEngine.com
- Google App Engine instance running the gae-boilerplate code (federated identity enabled)
Modifications
I played around with fiddler2 to see if I could learn anything more about the requests made to and from GAE. I compared the access logs from my OpenID server on WPEngine with the data I could pull from fiddler2 about the stackexchange OpenID server (openid.stackexchange.com).
XRDS-Simple Plugin
I modified this plugin to include an additional filter for the Wordpress HTTP headers:
add_filter('wp_headers', 'xrds_add_xrds_location');
function xrds_add_xrds_location($headers) {
error_log('Adding XRDS header', 0);
$headers['X-XRDS-Location'] = get_bloginfo('url').'/?xrds';
return $headers;
}
After that I modified the xrds_write()
function to simply return the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
xmlns:xrds="xri://$xrds"
xmlns:openid="http://openid.net/xmlns/1.0"
xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="10">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://axschema.org/contact/email</Type>
<URI>http://goff.wpengine.com/index.php/openid/server</URI>
</Service>
</XRD>
</xrds:XRDS>
This got rid of the http://www.google.com/gen_204?reason=EmptyURL
redirect and simply returned a HTTP 500
error.
Curious, I tried various different things to get any response out of GAE (remember GAE does not show error that occur in the /_ah/
handlers.
As a last resort I modified the <URI>
element to be https
instead of http
. This did the trick! I was successfully redirected to goff.wpengine.com
and was asked to verify that I wanted to login. Excited, I clicked verify. PHP Fatal error: Call to a member function needsSigning() on a non-object
. Balls. At least now I could ascertain problems from the PHP error log.
OpenID Plugin
After some quick Googling I found a thread on Google Code for the OpenID plugin. People had had similar issues and the consensus was that it was due to a plugin conflict. Comment #55
from user infinite.alis
mentioned that adding the Relying Party to the user's 'Trusted Sites' consistently solved the problem. Lo and behold, after adding the address to my trusted sites the entire authentication flow completed without error!
Conclusion
I have yet to do a post mortem to figure out which of the changes to XRDS-Simple made the difference. I suspect that simply changing the <URI>
element in XRDS-Simple to https
would solve the problem (My previous tests with SSL only focused on making sure the users.create_login_url()
function was passed a secure address, not that the XRDS file described the OpenID server via a secure address). Possibly need to play around with the filters for get_bloginfo('url')
in the xrds_write()
function.