I've searched the site but can't find anything that exactly matches this situation.
Trying to implement Federated login on GAE, using the sample python code at https://developers.google.com/appengine/docs/python/users/
, with a custom OpenID Provider. GAE returns either at HTTP 500 or HTTP 204 depending on the server setup. There are no entries in the application logs on the admin console. Most likely it is a problem to do with the XRDS file and the discovery process. I'd appreciate any suggestions as to a cause or possible debugging methods. Thanks in advance.
The code works fine when using the following providers in the 'federated_identity' parameter of the users.create_login_url()
function:
https://www.google.com/accounts/o8/id
The issues start when trying to use our own custom OpenID Provider. We have set up the OpenID plugin on a couple of Wordpress installs on different hosts for testing purposes. The plugin makes use of XRDS-Simple to publish the XRDS document at domain.com/?xrds
. Example document contents:
<?xml version="1.0" encoding="UTF-8" ?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns:openid="http://openid.net/xmlns/1.0">
<XRD xml:id="main" version="2.0">
<Type>xri://$xrds*simple</Type>
<!-- OpenID Consumer Service -->
<Service priority="10">
<Type>http://specs.openid.net/auth/2.0/return_to</Type>
<URI>https://goff.wpengine.com/index.php/openid/consumer</URI>
</Service>
<!-- OpenID Provider Service (0) -->
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<URI>https://goff.wpengine.com/index.php/openid/server</URI>
<LocalID>http://specs.openid.net/auth/2.0/identifier_select</LocalID>
</Service>
<!-- AtomPub Service -->
<Service priority="10">
<Type>http://www.w3.org/2007/app</Type>
<MediaType>application/atomsvc+xml</MediaType>
<URI>https://goff.wpengine.com/wp-app.php/service</URI>
</Service>
</XRD>
I have verified that the OpenID provider works by using it to log in to other OpenID enabled sites, including other Wordpress installs with the OpenID plugin and Stackoverflow.
When using the login link http://api.lighthouseuk.net/_ah/login_redir?claimid=https://goff.wpengine.com/?xrds&continue=http://api.lighthouseuk.net/
GAE returns a HTTP 500
error after several seconds. We haven't found any reason for this - there are no log entries in the admin console - but I suspect it may have something to do with the configuration on wpengine.com not returning the XRDS file or caching an incorrect one.
We have semi-confirmed this by running an identical setup on our dev server which has no caching enabled. Now when we visit the login link GAE returns a HTTP 302
response followed by a HTTP 204
response: http://www.google.com/gen_204?reason=EmptyURL
.
As far as I can tell, after requesting the XRDS file GAE makes no further requests to our server. This leads me to believe that there might be a problem with the XRDS file but I can't find any details in the documentation about required attributes.
If you send an authentication request to the URI specified in the XRDS document the OpenID server responds correctly by prompting the user to log in. Again this suggests that GAE takes issues with the XRDS file because no authentication request is made to our server. I can't figure out how to debug it when there are no errors recorded in the logs.
e.g. https://goff.wpengine.com/openid/server?openid.ns=http://specs.openid.net/auth/2.0&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select
&openid.return_to=http://api.lighthouseuk.net/checkauth&openid.realm=http://api.lighthouseuk.net/&openid.mode=checkid_setup
Obviously for a production environment we would be using SSL on both Wordpress and GAE but currently this is just a proof of concept. cURL, by default I believe, attempts to check the validity of SSL certificates so we've tried various combinations of SSL setting, including having none at all. Seemingly no effect.
As the XRDS document, by default, points to /index.php/openid/server/ we attempted different combinations of permalink setting in Wordpress to see if it had any effect. It didn't.
URL encoding the claimid seemed to have no effect - we still received the HTTP 204 response.
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.
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.
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).
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.
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!
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.