Как реализовать аутентификацию OpenID на основе Direct Identity с Zend OpenID

Я использую Zend framework и селектор openid из http://code.google.com/p/openid-selector/ - однако я обнаружил, что не могу войти в систему, используя такие сайты, как Google и Yahoo, поскольку они используют систему входа на основе прямой идентификации, при которой каждый просто перенаправляется на URL-адрес, а не на ввод уникального URL-адреса свои собственные для аутентификации.

Я проверил много вариантов и хаков, но ни один из них, похоже, не работает. Как я могу заставить это работать здесь, кстати - как это реализовано при переполнении стека? Мне действительно нужна вся помощь, ребята ..


Редактировать

Что ж, проблема здесь в том, что из того, что я заметил, это то, что класс Zend OpenID не поддерживает OpenID 2.0, дело в том, что типичный поставщик открытого идентификатора дает вам уникальный URL-адрес, такой как your-name.openid-providor.com или openid -providor.com/your-name, а класс Zend OpenId просто анализирует этот URL-адрес и затем перенаправляет вас на веб-сайт провайдера, откуда после аутентификации вы будете перенаправлены обратно.

В случае Yahoo и google - вы не вводите уникальный URL-адрес, вместо этого вы перенаправляетесь на сайт входа в систему Providors, а при входе в систему и аутентификации вас перенаправляют обратно - так что в основном происходит то, что объект zend_openID, когда он анализирует, чтобы сказать, кто провайдер не может отличить от самого общего URL-адреса. Например, когда вы нажимаете ссылку Google, она перенаправляет вас на https://www.google.com/accounts/o8/id

Это больше проблема с объектом zend openid здесь, и на форумах, связанных с zend, нет никакой помощи - поэтому мне было интересно, если кто-то уже взломал или внес изменения, которые я мог бы внести в класс для достижения этой цели. Извините, если я что-то упускаю, но я новичок в этом и программировании с открытым идентификатором и только начал замочить ноги.


Спасибо за продолжение - я проверял RPX некоторое время назад, и у них есть класс php, но я не смог его проверить, плюс я действительно просто хочу сейчас использовать селектор кода, как в stackoverflow, для работы с Yahoo и Аутентификация Google. Должен быть какой-то способ настроить синтаксический анализ, который класс Zend OpenID использует, поскольку он выполняет серию проверок регулярных выражений, чтобы сделать открытие.


person Ali    schedule 12.04.2009    source источник


Ответы (7)


Немного поздно в игре, но я смог заставить это работать с некоторыми хаками, которые я нашел в сети.

Первый. Yahoo. Все, что мне нужно было сделать, чтобы заставить Yahoo работать, - это изменить JavaScript так, чтобы он использовал me.yahoo.com вместо просто yahoo.com, и он отлично работал с версией Zend. Я использую фреймворк. К сожалению, Google по-прежнему не работал, так что некоторые взломы были в порядке.

Все эти изменения внесены в Zend/OpenId/Consumer.php

Во-первых, в методе _discovery добавьте следующее в серию проверок preg_match, которая начинается примерно со строки 740.

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

Я добавил это прямо перед оператором return false; в блоке else {}.

Во-вторых, в методе _checkId вам нужно будет добавить 3 новых блока (я еще не изучил достаточно, чтобы узнать, что вызывает каждый из этих трех случаев, поэтому я рассмотрел все, чтобы быть в безопасности.

Внутри блока $ version ‹= 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 (defined ('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 ‹= 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';
}

Ссылка на ошибку в Zend Framework Issue Tracker

person Steven Surowiec    schedule 09.05.2009
comment
Довольно поздно - но, опять же, спасибо за подсказку, и я определенно добавлю это в закладки для любого другого проекта - на данный момент я тщательно настроил и интегрировал библиотеку JanRain в свой код. Спасибо за информацию ;) - person Ali; 10.05.2009
comment
Эти три блока вызываются в зависимости от того, запущены ли уже как сеанс и связанные классы сеанса Zend. Первый блок является истинным, если Zend_Session использовался для запуска сеанса и хранится в переменной _session объекта-потребителя. Второй блок верен, если сеанс был запущен с помощью session_start () или session.auto_start. Последний блок запускает новый сеанс с Zend_Session_Namespace - person bearvrrr; 29.09.2010

Мне нужно использовать материал Google OpenID, я попробовал код Стивена и не смог заставить его работать как есть. Я внес некоторые изменения.

Метод изменения _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 */

Я считаю, что это было единственное изменение, которое мне пришлось сделать. Я почти уверен, что здесь должна быть некоторая проверка, связанная с вышеизложенным, из соображений безопасности, но я еще не изучил это достаточно глубоко, чтобы увидеть, какими они будут.

person Community    schedule 17.08.2009
comment
Спасибо за совет - я просто отказался от класса Zend и вместо него включил библиотеку JanRains OpenID. Подумал, что если бы мне пришлось взломать существующий код, было бы лучше создать свой собственный класс-оболочку на более надежной модели кода. - person Ali; 19.08.2009

Просматривая все предоставленные советы - я решил отказаться от использования класса zend_openid [извините за этот zend], и вместо этого я переключился на использование библиотеки JanRains OpenID. На то, чтобы запустить его вместе с моим проектом, потребовалось несколько часов, но, по крайней мере, он работает как ветер. Пришлось много взламывать и перетекать немного кода, чтобы заставить его работать, но оно того стоит.

Я не мог использовать какой-либо из адаптеров Zend с Zend-Auth для установки этой новой библиотеки кода, поскольку библиотека сама выполняла аутентификацию. Итак, я взломал и сделал общий адаптер, который только что вернул заполненный zend_result, установленный для объекта Auth, поэтому я аутентифицирую, используя свою библиотеку, и просто сохраняю результат в объекте Auth, извлекая немного быстрый объект Zend-Auth вместо того, чтобы иметь чтобы снова переписать мой код.

Библиотека доступна по адресу http://openidenabled.com/php-openid/.

Спасибо за всю помощь, ребята.

person Ali    schedule 16.04.2009

У меня похожие проблемы. Я планирую использовать RPX сейчас с Zend Framework. Может напишу переходник. Просто чтобы вы знали.

Информация: «RPS now» предоставляет универсальный интерфейс и пользовательский интерфейс для регистрации пользователей с помощью

  • facebook
  • Google
  • Yahoo
  • mySpaceID
  • Windows LiveID
  • OpenID
  • аол
person markus    schedule 15.04.2009

Я почти уверен, что Yahoo работает только с OpenID 2.0. Если вы хотите поддерживать пользователей Yahoo, вам придется перейти на библиотеку с поддержкой 2.0. Это будет больше, чем просто подправить парсинг.

person keturn    schedule 15.04.2009

Вы читали руководство - основы Zend_OpenId_Consumer? Посмотрите 38.2.2 на этой странице и дайте мне знать, поможет ли это, потому что должно.

В частности, я не знаю, предлагает ли Google OpenID. Я знаю, что Yahoo сработал, потому что некоторое время назад пробовал.

person Till    schedule 12.04.2009
comment
На самом деле я использую именно этот фрагмент кода в руководстве. Однако он вообще не работает с Google и Yahoo. Я пробовал несколько хаков в Интернете, но они не работают :(, кстати, как переполнение стека выполнило это? - person Ali; 14.04.2009
comment
@Ali Stackoverflow построен на asp.net (я думаю). В любом случае, я бы посоветовал вам предоставить дополнительную информацию, например ваш код, ваше сообщение об ошибке - тогда я могу попытаться помочь. Или вы отправляете сообщение в список рассылки fw-general @. - person Till; 14.04.2009
comment
Google не предоставляет openID, у Google есть собственный GoogleID, который можно связать с openID. - person markus; 15.04.2009

Спасибо за информацию. Я начал с использования библиотеки JanRain, но у меня проблемы с работой Simple Registration: мне не удалось получить данные таким образом. И нет документации по использованию Attribute Exchange. :(

Итак, я нашел и попробовал Zend / OpenId, но столкнулся с той же проблемой, что и вы: нет Yahoo !, Google и неизвестно, что еще поддерживает. Читая это, мне кажется, мне придется вернуться к JanRain; В моем случае RPX не подходит, так как это сторонний сервис.

person Jānis Elmeris    schedule 02.05.2009
comment
Немного больно заставить его работать с JanRain, но он очень надежный. Вам необходимо создать адаптер аутентификации, который является полностью универсальным и не выполняет никакой аутентификации, поскольку вся аутентификация будет выполняться JanRain. Созданный вами универсальный адаптер будет просто возвращать базовую информацию при аутентификации из janrain, такую ​​как код OpenID и все, что вы выберете для заполнения адаптера ... - person Ali; 19.08.2009
comment
JanRain - это боль. Прискорбно осознавать, что Zend - тоже боль :( - person jayarjo; 10.07.2010