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

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

I'm using the Zend framework and the openid selector from http://code.google.com/p/openid-selector/ - however I find I can't login using sites like Google and Yahoo as they use direct identity based login system whereby one is just redirected to a url as opposed to entering a unique url of their own for authentication.

我检查了许多选项和技巧,但似乎没有一个有效.顺便说一句,我怎样才能让它在这里工作 - 它是如何在堆栈溢出时实现的?我真的可以利用这里的所有帮助..

I've checked out many options and hacks but none of them seem to work. How can i get this to work here btw - how is it implemented at stack overflow? I could really use all the help here guys..

编辑

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

Well the issue here is that from what I have noticed is that the Zend OpenID class doesn't support OpenID 2.0 the thing is that a typical open ID providor gives you a unique url such as your-name.openid-providor.com or openid-providor.com/your-name and the Zend OpenId class just parses through that url and then redirects you to the providor website where upon authentication you are redirected back.

在雅虎和谷歌的情况下 - 你不输入唯一的 url 而是你被重定向到提供者登录站点,在登录和身份验证后你被重定向回来 - 所以基本上是什么是 zend_openID 对象解析时告诉谁是提供者,它无法从一般 url 本身中分辨出来.就像当您点击 Google 链接时,它会将您重定向到 https://www.google.com/帐户/o8/id

In the case of Yahoo and google - you don't enter a unique url instead you are redirected to the providors login site and upon login and authentication you are redirected back - so basically whats happeining is that the zend_openID object when it parses to tell who the providor is it fails to tell from the general url itself. Like when you click on teh Google link it redirects you to https://www.google.com/accounts/o8/id

这里更多是 zend openid 对象的问题,并且在 zend 相关论坛上没有任何帮助 - 所以我想知道是否有人已经入侵或对类进行了更改以实现此目的.抱歉,如果我遗漏了一些东西,但我对此有点陌生,并且使用开放 ID 进行编程,并且刚刚开始涉足.

Its more an issue with the zend openid object here and there isn't any help on zend related forums - so I was wondering if someone had already hacked or had an alteration I could make to the class to accomplish this. Sorry if I'm missing something but I'm kinda new to this and programming with open ID and have just started to get my feet wet.

感谢您的跟进 - 不久前我确实检查了 RPX,他们确实有一个 php 类,但我无法检查它加上我现在真的只想让在 stackoverflow 上使用的代码选择器工作与雅虎和谷歌身份验证.必须有某种方法来调整 Zend OpenID 类使用的解析,因为它运行一系列正则表达式检查以进行发现.

Thanks for the follow up - I did check into RPX a while back and they do have a php class but I wasnt able to check it out plus I really just want to for now get the code selector used as on stackoverflow to work with Yahoo and Google authentication. There has to be some kind of way to tweak the parsing which the Zend OpenID class uses as it runs a series of regular expression checks to make a discovery.

推荐答案

游戏有点晚了,但我能够利用我在互联网上发现的一些技巧来解决这个问题.

Little late to the game but I was able to get this working with some hacks I found around the interwebs.

首先.雅虎.为了让 Yahoo 正常工作,我所要做的就是将 JavaScript 更改为使用 me.yahoo.com 而不是 yahoo.com 并且它与 Zend 版本完美配合我正在使用的框架.不幸的是,谷歌仍然没有,所以需要进行一些黑客攻击.

First. Yahoo. To get Yahoo working all I had to do was change the JavaScript to use me.yahoo.com instead of just yahoo.com and it worked perfectly with the version of the Zend Framework I'm using. Unfortunately Google still wasn't, so some hacking was in order.

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

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

First, in the _discovery method add the following on the series of preg_match checks that starts at around line 740.

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

我在 else {} 块中的 return false; 语句之前添加了这个.

I added this right before the return false; statement that's in the else {} block.

其次,在 _checkId 方法中,您需要添加 3 个新块(我还没有深入了解导致调用这三种情况中的每一种的原因,因此我涵盖了所有为了安全起见.

Second, in the _checkId method you'll need to add 3 new blocks (I haven't dug around enough to know what causes each of these three cases to be called, so I covered all to be on the safe side.

在 $version <= 2.0 块中,您会发现一个 if/else if/else 块.在第一个 if 语句 ($this->_session !== null) 中添加:

Inside the $version <= 2.0 block, you'll find an if/else if/else block. In the first if statement ($this->_session !== null) add this to the end:

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 (defined('SID') 块中将此添加到末尾:

In the else if (defined('SID') block add this to the end:

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 <= 2.0 块内)添加:

And then after the else block (so outside the if/else if/else block all together, but still inside the $version <= 2.0 block) add this:

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';
}

链接到 Zend 框架问题跟踪器中的错误

相关文章