Как реализовать OpenID-аутентификацию на основе Direct Identity с Zend OpenID
Я использую структуру Zend и селектор openid из http://code.google.com/p/openid-selector/ - однако я считаю, что не могу войти в систему, используя сайты, такие как Google и Yahoo, поскольку они используют систему входа в систему с прямым доступом, посредством которой один только перенаправляется на URL-адрес, а не на свой собственный уникальный URL-адрес для аутентификации.
Я проверил множество вариантов и хаков, но никто из них, похоже, не работает. Как я могу заставить это работать здесь btw - как он реализован при переполнении стека? Я мог бы реально использовать всю помощь здесь, ребята..
Изменить
Хорошо, проблема в том, что из того, что я заметил, является то, что класс Zend OpenID не поддерживает OpenID 2.0, дело в том, что типичный открытый идентификатор ID предоставляет вам уникальный URL-адрес, например, ваш-name.openid-askor. com или openid-providor.com/your-name, а класс Zend OpenId просто анализирует этот URL-адрес, а затем перенаправляет вас на сайт-провайдер, где после аутентификации вы перенаправлены назад.
В случае с Yahoo и google - вы не вводите уникальный URL-адрес, вместо этого вы перенаправляетесь на сайт входа в систему профайлов, а после авторизации и аутентификации вы перенаправляетесь обратно - так что в основном то, что happeining является тем, что объект zend_openID при его анализе чтобы рассказать, кто из провидец не может сказать из самого общего url. Например, когда вы нажимаете на ссылку Google, она перенаправляет вас на https://www.google.com/accounts/o8/id
Чем больше проблема с объектом zend openid здесь, но и там нет никакой помощи на форумах, связанных с zend, так что мне было интересно, если кто-то уже взломал или имел изменения, которые я мог бы внести в класс, чтобы выполнить это. Извините, если я что-то пропустил, но я немного новичок в этом и программировал с открытым идентификатором и только начал мочить ноги.
Спасибо за продолжение - я проверил RPX некоторое время назад, и у них есть класс php, но я не смог его проверить, плюс я просто хочу, чтобы на данный момент вы выбрали селектор кода, который использовался как на stackoverflow для работы с проверкой подлинности Yahoo и Google. Должен быть какой-то способ настроить синтаксический анализ, который использует класс Zend OpenID, поскольку он выполняет серию проверок регулярных выражений, чтобы сделать обнаружение.
Ответы
Ответ 1
Немного поздно в игру, но я смог получить эту работу с некоторыми хаками, которые я нашел вокруг межсетевых экранов.
Во-первых. 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 Отслеживание ошибок
Ответ 2
Мне нужно использовать материал 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 */
Я считаю, что это было единственное изменение, которое я должен был сделать. Я почти уверен, что должна быть какая-то проверка, связанная с вышеуказанным по соображениям безопасности, но я не смотрел достаточно далеко, чтобы посмотреть, что они будут.
Ответ 3
Перейдя все советы - я решил портить класс zend_openid [извините за этот zend], и вместо этого я переключился на использование библиотеки OpenID от JanRains. Его заняло несколько часов, чтобы получить его и запустить с моим проектом, но по крайней мере его работа, как ветер. Должен был сделать много взлома и немного кода, чтобы заставить его работать, но его стоит.
Я не мог использовать какие-либо из адаптеров Zend с Zend-Auth, чтобы решить эту новую библиотеку кода, поскольку сама библиотека выполнила аутентификацию. Итак, я взломал и сделал универсальный адаптер, который только что вернул заполненный zend_result, установленный для объекта Auth, таким образом, я аутентифицирую свою библиотеку и просто сохраняю результат в объекте Auth, потянув немного быстрый один объект Zend-Auth, а не снова переписать мой код.
Библиотека доступна по адресу http://openidenabled.com/php-openid/
Спасибо за помощь всем ребятам.
Ответ 4
Я имею дело с подобными проблемами. Я планирую использовать RPX сейчас с Zend Framework. Возможно, я напишу адаптер. Просто чтобы вы знали.
Информация: "RPS now" предоставляет интерфейс "все-в-одном" и пользовательский интерфейс для регистрации пользователя с помощью
- facebook
- Google
- Yahoo
- MySpaceID
- Windows LiveID
- OpenID
- AOL
Ответ 5
Я уверен, что Yahoo работает только с OpenID 2.0. Если вы хотите поддерживать пользователей Yahoo, вам придется перейти на библиотеку с поддержкой 2.0. Это будет нечто большее, чем настройка некоторых парсинга.
Ответ 6
Вы проверили руководство - Основы Zend_OpenId_Consumer? Проверьте 38.2.2
на этой странице и сообщите мне, если это поможет, потому что это должно быть.
В частности, я не знаю, предлагает ли Google OpenID. Я знаю, что Yahoo работал, потому что я пробовал это некоторое время назад.
Ответ 7
Спасибо за информацию. Я начал с использования библиотеки JanRain, но у меня проблемы с получением Simple Registration для работы: мне не удалось получить какие-либо данные таким образом. И нет документации по использованию Exchange Attribute.: (
Итак, я нашел и пытался Zend/OpenId, но имел ту же проблему, что и вы: нет Yahoo!, Google и кто знает, что еще поддерживает. Читая это, мне кажется, что мне нужно вернуться к JanRain; RPX не является вариантом в моем случае, поскольку это сторонняя служба.