Как реализовать аутентификацию OpenID на основе прямой идентификации с помощью Zend OpenID
Я использую платформу Zend и селектор openid из http://code.google.com/p/openid-selector / - однако я обнаружил, что не могу войти в систему с помощью таких сайтов, как Google и Yahoo, поскольку они используют систему входа на основе прямой идентификации, при которой пользователь просто перенаправляется на URL-адрес, а не вводит собственный уникальный URL-адрес для аутентификации.
Я проверил множество вариантов и хаков, но ни один из них, похоже, не работает. Как я могу заставить это работать здесь, кстати, - как это реализовано в stack переполнение? Мне бы очень пригодилась вся помощь здесь, ребята..
Редактировать
{OpenID}Ну, проблема здесь в том, что, как я заметил, класс Zend OpenID не поддерживает OpenID 2.0. Дело в том, что типичный поставщик открытых идентификаторов предоставляет вам уникальный 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, нет никакой помощи - поэтому мне было интересно, не взломал ли кто-нибудь уже или не внес ли я изменения в класс, чтобы выполнить это. Извините, если я что-то упускаю, но я немного новичок в этом и программировании с открытым идентификатором и только начал мочить ноги.
Спасибо за продолжение - некоторое время назад я зарегистрировался в RPX, и у них действительно есть класс php, но я не смог его проверить, плюс я действительно просто хочу сейчас получить селектор кода, используемый как в stackoverflow для работы с аутентификацией Yahoo и Google. Должен быть какой-то способ настроить синтаксический анализ, который использует класс Zend OpenID при выполнении серии проверок регулярных выражений для обнаружения.
7 answers
Немного поздно для игры, но я смог заставить это работать с некоторыми взломами, которые я нашел в Интернете.
Во-первых. 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 ($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, если/else все вместе, но все еще внутри блока $version
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
Мне нужно использовать 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 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 */
Я считаю, что это было единственное изменение, которое я должен был делать. Я почти уверен, что по соображениям безопасности должна быть проведена какая-то проверка, связанная с вышеизложенным, но я недостаточно глубоко изучил это, чтобы понять, какими они будут.
Повторяя все предоставленные советы - я решил отказаться от использования класса zend_openid [извините за этот zend], и вместо этого я переключился на использование библиотеки Janrains OpenID. Потребовалось несколько часов, чтобы запустить и запустить мой проект, но, по крайней мере, он работает как ветер. Пришлось сделать много взломов и немного кода, чтобы заставить его работать, но оно того стоило.
Я не мог использовать ни один из адаптеров Zend с Zend-Auth для настройки этой новой библиотеки кода, как это сделала библиотека аутентификация сама по себе. ПОЭТОМУ я взломал и создал универсальный адаптер, который только что вернул заполненный набор zend_result для объекта аутентификации, поэтому я аутентифицируюсь с помощью своей библиотеки и просто сохраняю результат в объекте аутентификации, немного ускоряя объект Zend-Auth, вместо того, чтобы снова переписывать мой код.
Библиотека доступна по адресу http://openidenabled.com/php-openid/
Спасибо за всю помощь, ребята.
Я занимаюсь аналогичными проблемами. Я планирую использовать RPX сейчас с Zend Framework. Может быть, я напишу адаптер. Просто чтобы ты знал.
Информация: "RPS now" предоставляет универсальный интерфейс и пользовательский интерфейс для регистрации пользователей с помощью
- Yahoo
- MySpaceID
- Windows LiveID
- Идентификатор открытия
- aol
Я почти уверен, что Yahoo работает только с OpenID 2.0. Если вы хотите поддерживать пользователей Yahoo, вам придется перейти на библиотеку с поддержкой 2.0. Это будет вопрос большего, чем просто настройка некоторого синтаксического анализа.
Вы ознакомились с руководством --Основы Zend_OpenId_Consumer? Проверьте 38.2.2
на этой странице и дайте мне знать, если это поможет, потому что так и должно быть.
В частности, я не знаю, предлагает ли Google OpenID. Я знаю, что Yahoo работал, потому что я пробовал это некоторое время назад.
Спасибо за информацию. Я начал с использования библиотеки JanRain, но у меня возникли проблемы с получением простой регистрации для работы: мне не удалось получить какие-либо данные таким образом. И нет никакой документации по использованию обмена атрибутами. :(
Итак, я нашел и пытался использовать Zend/OpenID, но у меня была та же проблема, что и у вас: нет поддержки Yahoo!, Google и кто знает, что еще поддерживает. Читая это, кажется, мне придется вернуться к JanRain; RPX в моем случае не вариант, так как это третья сторона обслуживание.