Лучший способ реализовать Single-Sign-On со всеми основными поставщиками?

Я уже много исследовал эту тему и сам реализовал множество решений.

Включая OpenID, Facebook Connect (используя старый API-интерфейс Rest API и новый API API OAuth 2.0), войдите в систему с твиттером (который до сих пор был доведен до полной квалификации OpenID, насколько я знаю) и так далее …

Но то, чего я все еще не хватает, – это идеальное решение в одном решении.

Во время моих исследований я наткнулся на некоторые интересные проекты:

  • Janrain (ранее RPX) – коммерческое решение
  • Gigya – бесплатное, но внешнее решение с поддержкой javascript и rest apis
  • AnyOpenID – бесплатное решение для клиентов, коммерческих сайтов

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

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

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

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

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

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

Последнее из трех решений выше выглядит многообещающим из концепции. Все просто портировано на синтетический OpenID, а на веб-сайте должен реализоваться OpenID.

Через некоторое время я нашел Django socialauth , систему аутентификации на основе python для веб-графики Django. Но похоже, что он работает, как описано выше, и я думаю, что это та же система входа, которую использует Stackoverflow (или, по крайней мере, некоторые модифицированные fork …).

Я загрузил его и попытался настроить его и посмотреть, может ли он быть настроен как автономное решение, но мне не повезло, так как я тоже не попал в python.

Мне бы понравилось решение на базе PHP.

Итак, после этого длинного текста мой вопрос точно таков:

  • Как бы вы реализовали SSO, любую лучшую идею, чем портирование всего и наличие OpenID в качестве основы?
  • Каковы плюсы и минусы этого?
  • Знаете ли вы какие-либо уже существующие решения? Предпочтительно открытый источник.

Надеюсь, этот вопрос не слишком субъективен, спасибо заранее.

Обновление: я пришел к выводу, что создание прокси / обертки или то, что вы могли бы назвать ее для Facebook, чтобы перенести его в OpenID, чтобы он стал конечной точкой / провайдером OpenID, был бы лучшим вариантом. Так что именно то, что я сделал.

См. Мой ответ ниже.

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

Как оригинальный автор этого ответа, я хочу отметить, что считаю его ОТНОШЕНИЕМ . Поскольку большинство провайдеров решило исключительно реализовать Oauth вместо Openid. Более новые сервисы Openid также, вероятно, будут использовать openid connect, основанное на oauth. Есть хорошие библиотеки, например, например: https://github.com/hybridauth/hybridauth

После обсуждения уже существующего ответа подытожим:

Почти каждый крупный поставщик – провайдер / конечная точка openid, включая Google, Yahoo, Aol.

Некоторые из них требуют, чтобы пользователь указал имя пользователя для создания конечной точки openid. Некоторые из них (упомянутые выше) имеют открытые URL-адреса, где идентификатор пользователя автоматически возвращается, так что пользователю нужно только щелкнуть. (я был бы рад, если бы кто-то мог объяснить технический фон)

Однако единственной болью в заднице является Facebook, потому что у них есть Facebook-соединение, где они используют адаптированную версию OAuth для аутентификации.

Теперь то, что я сделал для моего проекта, – это настроить провайдера openid, который аутентифицирует пользователя с учетными данными моего приложения facebook – поэтому пользователь подключается к моему приложению – и возвращает идентификатор пользователя, который выглядит так:

http://my-facebook-openid-proxy-subdomain.mydomain.com/?id=facebook-user-id 

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

Поэтому мой сайт просто должен реализовать opend id, и я в порядке 🙂

Я создаю его на классах, которые вы можете найти здесь: http://gitorious.org/lightopenid

В моем файле index.php я просто вызываю его так:

 <?php require 'LightOpenIDProvider.php'; require 'FacebookProvider.php'; $op = new FacebookProvider; $op->appid = 148906418456860; // your facebook app id $op->secret = 'mysecret'; // your facebook app secret $op->baseurl = 'http://fbopenid.2xfun.com'; // needs to be allowed by facebook $op->server(); ?> 

и исходный код FacebookProvider.php следует:

 <?php class FacebookProvider extends LightOpenIDProvider { public $appid = ""; public $appsecret = ""; public $baseurl = ""; // i have really no idea what this is for. just copied it from the example. public $select_id = true; function __construct() { $this->baseurl = rtrim($this->baseurl,'/'); // no trailing slash as it will be concatenated with // request uri wich has leading slash parent::__construct(); # If we use select_id, we must disable it for identity pages, # so that an RP can discover it and get proper data (ie without select_id) if(isset($_GET['id'])) { // i have really no idea what happens here. works with or without! just copied it from the example. $this->select_id = false; } } function setup($identity, $realm, $assoc_handle, $attributes) { // here we should check the requested attributes and adjust the scope param accordingly // for now i just hardcoded email $attributes = base64_encode(serialize($attributes)); $url = "https://graph.facebook.com/oauth/authorize?client_id=".$this->appid."&redirect_uri="; $redirecturl = urlencode($this->baseurl.$_SERVER['REQUEST_URI'].'&attributes='.$attributes); $url .= $redirecturl; $url .= "&display=popup"; $url .= "&scope=email"; header("Location: $url"); exit(); } function checkid($realm, &$attributes) { // try authenticating $code = isset($_GET["code"]) ? $_GET["code"] : false; if(!$code) { // user has not authenticated yet, lets return false so setup redirects him to facebook return false; } // we have the code parameter set so it looks like the user authenticated $url = "https://graph.facebook.com/oauth/access_token?client_id=148906418456860&redirect_uri="; $redirecturl = ($this->baseurl.$_SERVER['REQUEST_URI']); $redirecturl = strstr($redirecturl, '&code', true); $redirecturl = urlencode($redirecturl); $url .= $redirecturl; $url .= "&client_secret=".$this->secret; $url .= "&code=".$code; $data = $this->get_data($url); parse_str($data,$data); $token = $data['access_token']; $data = $this->get_data('https://graph.facebook.com/me?access_token='.urlencode($token)); $data = json_decode($data); $id = $data->id; $email = $data->email; $attribute_map = array( 'namePerson/friendly' => 'name', // we should parse the facebook link to get the nickname 'contact/email' => 'email', ); if($id > 0) { $requested_attributes = unserialize(base64_decode($_GET["attributes"])); // lets be nice and return everything we can $requested_attributes = array_merge($requested_attributes['required'],$requested_attributes['optional']); $attributes = array(); foreach($requested_attributes as $requsted_attribute) { if(!isset($data->{$attribute_map[$requsted_attribute]})) { continue; // unknown attribute } $attributes[$requsted_attribute] = $data->{$attribute_map[$requsted_attribute]}; } // yeah authenticated! return $this->serverLocation . '?id=' . $id ; } die('login failed'); // die so we dont retry bouncing back to facebook return false; } function get_data($url) { $ch = curl_init(); $timeout = 5; curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); $data = curl_exec($ch); curl_close($ch); return $data; } } 

Его просто первая рабочая версия (быстрая и грязная). Некоторые динамические материалы жестко привязаны к моим потребностям. Он должен показать, как и что это можно сделать. Я счастлив, если кто-то подхватит и улучшит его, или напишет его или что-то еще 🙂

Ну, я считаю, что этот вопрос ответил

но я добавляю щедрость, чтобы обсудить. Я хотел бы знать, что вы думаете о моем решении.

Я награжу награду лучшим ответом / комментарием рядом с этим.

OpenID будет вашим лучшим выбором для этого приложения. Это поддерживается многими провайдерами:

  • Google
  • Yahoo
  • MyOpenID
  • AOL

Единственная проблема заключается в том, что твиттер еще не реализовал OpenID. Вероятно, это связано с тем, что они являются фирмой, основанной на патентах, поэтому они хотели получить свое «собственное» решение.

Чтобы решить это решение, вы можете написать класс-оболочку для обеспечения совместимости с OpenID, но вероятность того, что даже если у ваших пользователей нет учетной записи Twitter, у них может быть учетная запись Facebook, Google или Yahoo.

Facebook Поддерживает oauth, поэтому вам придется переносить oauth на OpenID

Некоторые библиотеки PHP для OpenID можно найти здесь .

Теперь, некоторые вопросы были подняты о том, что facebook является поставщиком oauth.

Их URL-адрес: https://graph.facebook.com/oauth/authorize.

Если вы все еще не верите мне, тогда вы можете посмотреть этот файл javascript, где я получил этот URL. Если вы не верите этому файлу javascript, то обратите внимание, что он размещен в stackexchange, провайдере этого сайта. Теперь вы должны это принять.

Быстрая перемотка вперед на два года, и ответ «OpenID – это ответ», похоже, падает на обочину рядом крупных поставщиков. Большинство основных сторонних интеграционных сайтов, похоже, перешли на некоторый вкус OAuth (обычно OAuth2). Кроме того, если вы не возражаете против использования OpenID / OAuth, теперь есть полное решение SSO, написанное на PHP (отказ от ответственности и полное раскрытие: этот продукт разрабатывается и поддерживается мной под баннером CubicleSoft):

Сервер единого входа / клиента

Который не существовал, когда этот вопрос изначально был задан. У этого есть либеральная лицензия (MIT или LGPL) и соответствует вашему требованию быть уровнем абстракции. Проект, как правило, ориентирован на регистрацию предприятий, но в социальных сетях также есть значки социальных сетей (Google и Facebook).

Вы также можете посмотреть на HybridAuth , который ориентирован только на значки социальных сетей, но является скорее библиотекой, чем готовым решением, которое вы можете бросить на сервер и сделать с ним. Таким образом, есть немного больше работы, связанной с его настройкой. Это действительно зависит от того, что вам нужно.

Если вы довольны своим решением OpenID, то здорово, но сегодня есть больше вариантов, чем два года назад, и люди все еще находят эту тему.