Wednesday, November 14, 2012

Using mod_oauth_openid with Google Apps

Because of a recent release on a Jenkins plugin for Google Apps SSO, I wondered whether there was a way to get mod_oauth_openid without prompting a user to choose between Google Apps domains.  The basic approach would have been to set Apache configurations similar to the one described in this previous blog posting except for the following lines:
AuthOpenIDTrusted ^https://www.google.com/a/yourdomain.com/o8/ud
AuthOpenIDSingleIdP https://www.google.com/accounts/o8/site-xrds?hd=yourdomain.com
If you try to make mod_oauth_openid work with the configuration above, chances are you'll see "OP is not authorized to make an assertion regarding the identity".  This issue was encountered by another user in this thread (the Step2 libraries referred are the OpenID Google App discovery extensions that Google refers at https://code.google.com/p/step2/).  Unless a patch is made to mod_auth_openid or the underlying libokele C++ library to support these Google discovery extensions, chances are that you won't be able to use this approach.

The apparent problem is that Google has a special way of dealing with OpenID discovery process:

https://developers.google.com/google-apps/help/faq/auth#what_discovery
It is important to note that the RP must use a slightly different discovery mechanism to support Google Apps accounts, which is covered in depth here. In short, during the OpenID discovery process, RPs must check both (using example.com as theexample domain) https://www.google.com/accounts/o8/.well-known/host-meta?hd=example.com and http://example.com/.well-known/host-meta for discovery information, as the site owners may opt to have Google host this information, rather than host it themselves.
Basically it means that that when a user authenticates on Google Apps, you're given back not only a unique identifier for the user (known as the claimed id), along with a URL. If your domain is mydomain.com, the URL that is returned is http://mydomain.com/openid?id=<id>. In OpenID specs, this URL is expected to be available for you to grab metadata to determine where to inquire about this ID.  If an OpenID library tries to open this URL, chances are that it will 404 and therefore fail the user discovery process.

Google proposes that the users implementing Google Apps SSO look both at https://www.google.com/accounts/o8/.well-known/host-meta?hd=example.com or http://example.com/.well-known/host-meta. Neither of these URLs follow the OpenID spec since one of them requires you to host this metadata, but you also have to deal with digitally signing it too). The approach is summarized in the User Discovery section of the Google OpenID documentation.

The Jenkins OpenID and Python OpenID plugins skip this step and just assumes https://www.google.com/accounts/o8/user-xrds?uri= is the correct URL to use.  Normally the metadata would need to include this <URITemplate> tag, which then gets used to perform the user verification.

https://github.com/jenkinsci/openid-plugin/commit/91beef6857f0d7956ee0ad27ac24744f961ae6c2 
https://github.com/adieu/python-openid/commit/789cc11950e94c09e7c912a34b4e1d1d8f20c62b

More background here: 

http://www.slideshare.net/timdream/google-apps-account-as-openid https://sites.google.com/site/oauthgoog/fedlogininterp/openiddiscovery 

Also, someone else attempted to side-step this issue with Google Apps and mod_auth_openid, but it feels more of a way to circumvent some of the OpenID discovery process:

https://gist.github.com/2635479

No comments:

Post a Comment