如何使用Zend OpenID实现基于直接身份的OpenID身份验证

时间:2009-04-12 06:08:06

标签: php zend-framework authentication login openid

我正在使用Zend框架和来自http://code.google.com/p/openid-selector/的openid选择器 - 但是我发现我无法使用Google和Yahoo这样的网站登录,因为他们使用基于直接身份的登录系统,其中一个只是重定向到url,而不是输入自己的唯一网址进行身份验证。

我已经检查了很多选项和黑客,但它们似乎都没有用。我怎么能在这里使用它btw - 它是如何在堆栈溢出时实现的?我真的可以在这里使用所有的帮助..


修改

这里的问题是,我注意到Zend OpenID类不支持OpenID 2.0,因为典型的开放ID提供程序会为您提供一个唯一的URL,例如your-name.openid-providor。 com或openid-providor.com/your-name和Zend OpenId类只需解析该URL,然后将您重定向到providor网站,经过身份验证后,您将被重定向回来。

在雅虎和谷歌的情况下 - 你没有输入一个唯一的网址,而是你被重定向到提供者登录网站,登录和身份验证后你被重定向回来 - 所以基本上发生的是它解析时的zend_openID对象告诉谁是提供者,它无法从一般网址本身告诉。就像点击Google链接一样,它会将您重定向到https://www.google.com/accounts/o8/id

这里更多关于zend openid对象的问题,并且在zend相关论坛上没有任何帮助 - 所以我想知道是否有人已经入侵或者我可以对课程进行更改以实现此目的。对不起,如果我错过了一些东西,但我对此有点新鲜,并使用开放式ID进行编程,并且刚刚开始弄湿我的脚。


感谢您的跟进 - 我确实检查了RPX一段时间后他们确实有一个PHP类,但我无法检查它加上我真的只是想现在得到用于stackoverflow上的代码选择器工作使用Yahoo和Google身份验证。必须有某种方法来调整Zend OpenID类使用的解析,因为它运行一系列正则表达式检查来进行发现。

7 个答案:

答案 0 :(得分:9)

比赛迟到但我能够通过我在网站周围找到的一些黑客来解决这个问题。

首先。雅虎。要让雅虎工作,我所要做的就是将JavaScript改为使用 me.yahoo.com 而不仅仅是 yahoo.com ,它与Zend的版本完美配合我正在使用的框架。不幸的是谷歌仍然没有,所以有些黑客行为是有序的。

所有这些更改都在Zend/OpenId/Consumer.php

首先,在_discovery方法中,在740行左右开始的preg_match检查系列中添加以下内容。

} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
    $version = 2.0;
    $server = $r[1];

我在else {}块中的return false;语句之前添加了此权限。

其次,在_checkId方法中你需要添加3个新块(我没有足够的挖掘来知道是什么导致这三个案例中的每一个被调用,所以我将所有内容都包括在内安全的一面。

在$ version&lt; = 2.0块中,你会找到一个if / else if / else块。在第一个if语句中($this->_session !== null)将其添加到结尾:

if ($server == 'https://www.google.com/accounts/o8/ud') {
    $this->_session->identity = 'http://specs.openid.net/auth/2.0/identifier_select';
    $this->_session->claimed_id = 'http://specs.openid.net/auth/2.0/identifier_select';
}

在else if(已定义('SID')块中,将其添加到结尾:

if ($server == 'https://www.google.com/accounts/o8/ud') {
    $_SESSION['zend_openid']['identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
    $_SESSION['zend_openid']['claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}

然后在else块之后(所以在if / else if / else块之外都在一起,但仍在$ version&lt; = 2.0块内)添加:

if ($server == 'https://www.google.com/accounts/o8/ud') {
    $params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
    $params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}

Link to the bug in Zend Framework Issue Tracker

答案 1 :(得分:3)

我需要使用Google的OpenID内容,我尝试过Steven的代码,无法让它按原样运行。我做了一些修改。

_discovery更改方法仍然相同:

Zend / OpenId / Consumer.php,第765行,添加:

} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
    $version = 2.0;
    $server = $r[1];

其余的不同,但是:

Zend / OpenId / Consumer.php,第859行(进行上述更改后),添加:

if (stristr($server, 'https://www.google.com/') !== false) {
    $id = 'http://specs.openid.net/auth/2.0/identifier_select';
    $claimedId = 'http://specs.openid.net/auth/2.0/identifier_select';
}

这是正确的:

$params['openid.identity'] = $id;

$params['openid.claimed_id'] = $claimedId;

一旦获得授权,就让它返回ID:

Zend / Auth / Adapter / OpenId.php,第278行:

if(isset($_REQUEST['openid_identity']))
{
    $this->_id = $_REQUEST['openid_identity'];
    $id = $this->_id;
}

这是正确的:

return new Zend_Auth_Result(
    Zend_Auth_Result::SUCCESS,
    $id,
    array("Authentication successful"));

请注意,我尚未对此代码进行全面测试。下面的代码更加简单。

我花了更多时间,除了上述内容之外,我还使用以下更改与Google Apps域合作:

Zend / OpenId / Consumer.php,第734行

        $discovery_url = $id;
        if(strpos($discovery_url, '/', strpos($discovery_url, '//')+2) !== false) {
            $discovery_url = substr($discovery_url, 0, strpos($discovery_url, '/', strpos($discovery_url, '//')+2));
        }
        $discovery_url .= '/.well-known/host-meta';
        $response = $this->_httpRequest($discovery_url, 'GET', array(), $status);
        if ($status === 200 && is_string($response)) {
            if (preg_match('/Link: <([^><]+)>/i', $response, $r)) {
                $id = $r[1];
            }
        }

这是在以下之后:

/* TODO: OpenID 2.0 (7.3) XRI and Yadis discovery */

我相信这是我必须做出的唯一改变。我很确定出于安全原因应该对上述内容进行一些检查,但我还没有看得太清楚它们会看到它们会是什么。

答案 2 :(得分:2)

仔细阅读所有提供的建议 - 我决定放弃使用zend_openid类[对不起那个zend],而是转而使用JanRains OpenID库。花了几个小时才完成并运行我的项目,但至少它的工作就像一阵微风。不得不做很多黑客攻击和一些代码溢出来让它工作,但值得。

我无法使用任何Zend适配器与Zend-Auth来解决这个新的代码库,因为库自己进行了身份验证。所以我攻击并制作了一个通用的适配器,它只是将一个填充的zend_result集返回给Auth对象,因此我使用我的库进行身份验证,只将结果存储在Auth对象中,将一个快速的Zend-Auth对象拉出来而不是再次重写我的代码。

图书馆位于http://openidenabled.com/php-openid/

感谢所有帮助人员。

答案 3 :(得分:1)

我正在处理类似的问题。我打算在Zend Framework中使用RPX now。也许我会写一个适配器。只是为了让你知道。

信息:'RPS now'为用户注册

提供了一体化界面和用户界面
  • 谷歌
  • 雅虎
  • 的MySpaceID
  • Windows LiveID
  • 的OpenID
  • AOL

答案 4 :(得分:1)

我很确定Yahoo only works with OpenID 2.0。如果您想支持Yahoo用户,则必须升级到支持2.0的库。这不仅仅是调整一些解析。

答案 5 :(得分:0)

您是否查看了手册 - Zend_OpenId_Consumer basics?查看该页面上的38.2.2,如果有帮助,请告诉我,因为它应该。

具体来说,我不知道Google是否提供OpenID。我知道雅虎的工作是因为我已经尝试了一段时间。

答案 6 :(得分:0)

感谢您提供的信息。我开始使用JanRain的库,但是我在使用简单注册工作方面遇到了问题:我没有成功获取任何数据。并且没有关于使用Attribute Exchange的文档。 :(

所以,我发现并且正在尝试Zend / OpenId,但遇到了和你一样的问题:没有Yahoo!,Google以及谁知道还有什么支持。读到这个,似乎我必须回到JanRain; RPX不是我的选择,因为它是第三方服务。