开发者

Google's OpenID identifier is different depending on the "consumer" domain name. How to avoid problems if domain name needs to change?

I'm currently testing an OpenID implementation, and I'm noticing that Google sends a different identifier for different consuming host name / domain name, even for the same user. For example, Google sends a different identifier when the requesting site is localhost, compared to the identifier they send when the requesting site is 127.0.0.1 for the same user.

Note: I haven't actually tested this using public domain names, but I can't see why the behavior would be any different.

My concern with Google's behavior is that if we ever choose to change our website domain name in the future, then users will no longer be able to log in to开发者_Go百科 the website using Google's OpenId as the identity provider. This seems to be a big problem. Am I missing something, or are all OpenID consuming sites faced with this potential problem?

I've also tested this with MyOpenId, but the identifier that MyOpenId creates is fixed, so this wouldn't be a problem with them.


Have a look at Google OpenID most important technical issue. Some infos there. Basically a link taken from the accounts section of stackoverflow.com ;)

-sa


It appears that the OpenID URLs returned by Google depend on the openid.realm value that is used. Also, I just tried the OpenID process with a realm set to http://MYREALM and openid.return_to set to http://localhost/openid.php, but received an HTTP 400 Bad Request. Apparently, Google checks that the realm has the same domain (and probably port) as the "return to" URL.

One idea for a work-around is to store the Gmail address associated with the OpenID. Whenever you request a Google OpenID, always request the user's email address via Attribute Exchange's http://axschema.org/contact/email type. If you ever change domains, you can associate the new OpenID URL with their account based on the email address.

Note: It is imperative that you verify the HMAC-SHA1 signature. Otherwise, anyone would be able to "return to" your web application's OpenID checkauth action with a constructed email address, allowing them to take over someone's account if they know the target's Gmail address.

When a user is logging in with their Google Account for the first time after the switch, the migration procedure is:

  1. Send a POST request to https://www.google.com/accounts/o8/ud with the following parameters:

     +---------------------+----------------------------------+
     | openid.ns           | http://specs.openid.net/auth/2.0 |
     | openid.mode         | associate                        |
     | openid.assoc_type   | HMAC-SHA1                        |
     | openid.session_type | no-encryption                    |
     +---------------------+----------------------------------+
     

    (replace openid.realm=http://NEWREALM as appropriate)

    The response will be something like:

     ns:http://specs.openid.net/auth/2.0
     session_type:no-encryption
     assoc_type:HMAC-SHA1
     assoc_handle:B5hJNa39Cl39BXSOKMqkPpk03rJmE0GI6EhHBkvfLOBFAMMQX67HjuFq
     expires_in:46800
     mac_key:F5XUXvoYutLvFv4IzJS0diytLmbe
     
  2. With the redirect to the Service URI, https://www.google.com/accounts/o8/ud, mode 'checkid_setup', make sure to send the assoc_handle that was previously obtained as well as require the user's email address via Attribute Exchange. In other words, be sure to send the following, additional parameters:

     +----------------------+----------------------------------------------------------+
     | openid.assoc_handle  | B5hJNa39Cl39BXSOKMqkPpk03rJmE0GI6EhHBkvfLOBFAMMQX67HjuFq |
     | openid.ns.ax         | http://openid.net/srv/ax/1.0                             |
     | openid.ax.mode       | fetch_request                                            |
     | openid.ax.type.email | http://axschema.org/contact/email                        |
     | openid.ax.required   | email                                                    |
     +----------------------+----------------------------------------------------------+
     

    The "return to" request will include the important parameters openid_signed, openid_sig, and openid_ext1_value_email.

  3. Follow the OpenID Authentication 2.0 Specification's procedure for generating the signature. If the base64-encoding of the HMAC-SHA1 signature is not the same as the openid_sig value, then the signature is invalid. Note that the MAC key in this example is F5XUXvoYutLvFv4IzJS0diytLmbe. Use whatever Google's server sent back with the association request.

 

Google's Federated Login documentation page states that http://axschema.org/contact/email "[r]equests the user's gmail address". Presumably, once a Google Account is created then the "Gmail" email address is fixed. But, if this assumption is not valid, then it is not safe to use this procedure because a malicious user could change their email address as returned by the Federated Login Service to whatever the email address is of the account that they wish to steal.

Just to be on the safe side, before activating the new OpenID, send an email verification request to the email address. The verification link would contain a nonce associated with the new OpenID. Once the link is clicked, the new OpenID would be fully associated with the user's account as receipt of the nonce would verify the association between email address and new OpenID URL.

See also: openid.sig -- How is it generated?


There is another possible work-around. When making the indirect authentication request (redirecting to the Service URI), send the old OpenID URL as the values of the openid.claimed_id and openid.identity parameters even though realm is set to the new realm.

On my developer machine, I have the domain 'thiscomputer' aliased to 127.0.0.1. When I requested authentication from Google's OpenID Provider, realm 'http://thiscomputer' and openid.identity and openid.claimed_id both set to http://specs.openid.net/auth/2.0/identifier_select, I got back something like:

https://www.google.com/accounts/o8/id?id=VGwSBXN7Q00X4G9CTAsLPMJ3m6JaPljpkrURAUZJ

I then requested authentication from the OP, realm 'http://localhost' and openid.identity and openid.claimed_id both set to http://specs.openid.net/auth/2.0/identifier_select. I got back something like:

https://www.google.com/accounts/o8/id?id=VGwSBXNwzPQk-puNdfZl4tP-s7JNHPA3WmMHozHJ

I then requested authentication from the OP, realm 'http://localhost' and openid.identity and openid.claimed_id both set to https://www.google.com/accounts/o8/id?id=VGwSBXN7Q00X4G9CTAsLPMJ3m6JaPljpkrURAUZJ (the OpenID identity for my Google Account when realm is 'http://thiscomputer'). I got back:

https://www.google.com/accounts/o8/id?id=VGwSBXN7Q00X4G9CTAsLPMJ3m6JaPljpkrURAUZJ

That is, I got back the same OpenID identity URL as when realm is 'http://thiscomputer'. Thus, even though I "migrated" my OpenID-relying web app from 'thiscomputer' to 'localhost', I can still use the old OpenID identity URL.

This solution works as long as you know the user's old OpenID identity URL, perhaps because it is stored in a cookie.

One note: I tried setting openid.identity and openid.claimed_id to different values (e.g. one is http://specs.openid.net/auth/2.0/identifier_select while the other is https://www.google.com/accounts/o8/id?id=VGwSBXN7Q00X4G9CTAsLPMJ3m6JaPljpkrURAUZJ or one is https://www.google.com/accounts/o8/id?id=VGwSBXN7Q00X4G9CTAsLPMJ3m6JaPljpkrURAUZJ and the other is https://www.google.com/accounts/o8/id?id=VGwSBXNwzPQk-puNdfZl4tP-s7JNHPA3WmMHozHJ), but Google's OP service responded with "The page you requested is invalid."

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜