Как реализовать аутентификацию OpenID на основе Direct Identity с помощью Zend OpenID - PullRequest
16 голосов
/ 12 апреля 2009

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

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


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

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

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

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


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

Ответы [ 7 ]

9 голосов
/ 10 мая 2009

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

Во-первых. Yahoo. Чтобы заставить Yahoo работать, все что мне нужно было изменить JavaScript, чтобы использовать me.yahoo.com вместо yahoo.com , и это прекрасно работало с версией Zend Framework I пользуюсь. К сожалению, 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 <code>($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 <= 2.0) добавьте это: </p>

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

3 голосов
/ 17 августа 2009

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

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

И чтобы получить его, чтобы вернуть идентификатор, после авторизации:

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 со следующими изменениями, помимо перечисленных выше:

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 голосов
/ 16 апреля 2009

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

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

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

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

1 голос
/ 15 апреля 2009

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

1 голос
/ 15 апреля 2009

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

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

  • facebook
  • Google
  • Yahoo
  • MySpaceID
  • Windows LiveID
  • OpenID
  • 1020 * AOL *
0 голосов
/ 02 мая 2009

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

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

0 голосов
/ 12 апреля 2009

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

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

...