How do I implement Direct Identity based OpenID authentication with Zend OpenID

后端 未结 7 953
别那么骄傲
别那么骄傲 2020-12-07 17:55

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 the

相关标签:
7条回答
  • 2020-12-07 18:32

    Did you check out the manual -- Zend_OpenId_Consumer basics? Check out 38.2.2 on that page and let me know if this helps, because it should.

    Specifically, I don't know if Google offers OpenID. I know that Yahoo worked because I've tried it a while back.

    0 讨论(0)
  • 2020-12-07 18:33

    I'm pretty sure that Yahoo only works with OpenID 2.0. If you want to support Yahoo users, you're going to have to upgrade to a library with 2.0 support. That's going to be a matter of more than tweaking some parsing.

    0 讨论(0)
  • 2020-12-07 18:33

    Thanks for the information. I started by using JanRain's library, but I have problems with getting Simple Registration to work: I have not succeeded in getting any data that way. And there is no documentation on using Attribute Exchange. :(

    So, I found and was trying Zend/OpenId, but had the same problem as you: no Yahoo!, Google and who knows what else support. Reading this, it seems I'll have to get back to JanRain; RPX is not an option in my case as it's a third party service.

    0 讨论(0)
  • 2020-12-07 18:34

    I need to use Google's OpenID stuff, and I tried Steven's code and couldn't get it to work as-is. I've made some modifications.

    The _discovery change method is still the same:

    Zend/OpenId/Consumer.php, line 765, add:

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

    The rest is different, though:

    Zend/OpenId/Consumer.php, line 859 (after making the above change), add:

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

    This is right before:

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

    And to get it to return the ID, once authorized:

    Zend/Auth/Adapter/OpenId.php, line 278:

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

    This is right before:

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

    Note that I have not thoroughly tested this code. The code below is even more shakey.

    I have spent more time and I've gotten it to work with my Google Apps domain with the following changes, in addition to the above:

    Zend/OpenId/Consumer.php, line 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];
                }
            }
    

    This is right after:

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

    I believe that was the only change I had to make. I'm pretty sure there's supposed to be some checking involved with the above for security reasons, but I haven't looked far enough into it to see what they would be.

    0 讨论(0)
  • 2020-12-07 18:38

    Going over all the advice provided - I've decided to ditch using the zend_openid class [ sorry about that zend ] and instead I've switched to using JanRains OpenID library. Its taken a few hours to get it up and running with my project but atleast its working like a breeze. Had to make a lot of hacking and a bit of code spill over to get it working but its worth it.

    I couldn't use any of Zend adapters with Zend-Auth to settle this new code library in as the library did the authentication on its own. SO I hacked and made a generic adapter that just returned a filled zend_result set to the Auth object thus I authenticate using my library and merely store the result in the Auth object pulling a bit of a fast one one the Zend-Auth object rather than have to rewrite my code again.

    The library is available at http://openidenabled.com/php-openid/

    Thanks for all the help guys.

    0 讨论(0)
  • 2020-12-07 18:46

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

    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.

    All of these changes go in Zend/OpenId/Consumer.php

    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];
    

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

    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.

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

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

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

    Link to the bug in Zend Framework Issue Tracker

    0 讨论(0)
提交回复
热议问题