确保对请求网站的Google OpenID详细信息的潜在欺骗


Securing potential spoofing of Google OpenID details to requesting site

我可能错过了一些非常愚蠢的东西,也错过了Google Federated Login文档中的内容,但Google OpenID登录对请求网站来说实际上是如何安全的呢?请求网站如何知道来自谷歌的详细信息,而不仅仅是有人在URL中输入查询字符串参数?

为了说明,我正在用PHP实现一个基本的OpenID登录序列,所返回的似乎只是URL中的一组查询字符串参数,我可以使用这些参数来获取OpenID的详细信息,这非常有效。问题是,如果我只是手动在地址栏中输入这些内容,而没有实际登录谷歌,我的请求网站怎么会知道其中的区别?

首先,要求提供详细信息的表格:

<form method='post' action='https://www.google.com/accounts/o8/ud'>
    <input type='hidden' name='openid.return_to' value='http://www.example/com/logged-in' />
    <input type='hidden' name='openid.mode' value='checkid_setup' />
    <input type='hidden' name='openid.ns' value='http://specs.openid.net/auth/2.0' />
    <input type='hidden' name='openid.claimed_id' value='http://specs.openid.net/auth/2.0/identifier_select' />
    <input type='hidden' name='openid.identity' value='http://specs.openid.net/auth/2.0/identifier_select' />
    <input type='hidden' name='openid.ns.ax' value='http://openid.net/srv/ax/1.0' />
    <input type='hidden' name='openid.ax.mode' value='fetch_request' />
    <input type='hidden' name='openid.ax.required' value='email,firstname,lastname' />
    <input type='hidden' name='openid.ax.type.email' value='http://axschema.org/contact/email' />
    <input type='hidden' name='openid.ax.type.firstname' value='http://axschema.org/namePerson/first' />
    <input type='hidden' name='openid.ax.type.lastname' value='http://axschema.org/namePerson/last' />
    <input type='submit' value='Login With Google Account' />
</form>

这很好,把我带着一大堆URL参数送回http://www.example.com/logged-in的请求站点,如下所示(来自PHP print_r调用):

Array
(
    [openid_ns] => http://specs.openid.net/auth/2.0
    [openid_mode] => id_res
    [openid_return_to] => http://www.example.com/logged-in
    [openid_ext1_type_firstname] => http://axschema.org/namePerson/first
    [openid_ext1_value_firstname] => {user's first name}
    [openid_ext1_type_email] => http://axschema.org/contact/email
    [openid_ext1_value_email] => {user's e-mail address}
    [openid_ext1_type_lastname] => http://axschema.org/namePerson/last
    [openid_ext1_value_lastname] => {user's last name}
)

这太棒了,但我怎么知道这实际上是一个合法的请求,而不是有人在地址栏中输入上述参数?

感谢您的帮助,如果已经有人问过我(找不到任何副本!),如果我错过了一些明显的东西,我深表歉意!

在不涉及太多细节的情况下(如果需要血腥的细节,请阅读OpenID规范),OpenID协议对此有适当的保护措施。您收到的断言是经过签名和验证的,并且ID的名称空间有限制,以防止提供者伪造彼此的ID。如果你正在使用一个已建立的库(例如php-openid很好),你不必太担心这一点,因为它通常是在底层处理的。如果您正在尝试推出自己的实现。。。。好吧,只是不要。。。

也就是说,有些没有包含在协议中。例如,当属性在响应中签名时,除非您信任特定的提供者,否则您不能认为它们是准确的。一些应用程序会检查做出断言的提供商的URL/主机名(在验证响应后),并将进行正确电子邮件验证的已知身份提供商列入白名单。如果你需要一封经过验证的电子邮件,这样做可以获得更好的用户体验。但是,如果断言来自未知的身份提供商,请不要认为电子邮件地址实际上属于用户,除非您自己验证拥有该地址。