与所有主要供应商实施单点login的最佳方法?

我已经做了很多关于这个话题的研究,并且自己实现了很多的解决scheme。

包括OpenID,Facebook Connect(使用旧的Rest API和新的graphicsOAuth 2.0 API),使用twitterlogin(目前为止我已经升级到完全限定的OpenID),等等…

但是我仍然缺less的是一个完美的解决scheme。

在我的研究中,我偶然发现了一些有趣的项目:

  • Janrain(原RPX) – 商业解决scheme
  • Gigya – 一个免费的,但外部托pipe的解决scheme与JavaScript和restapis
  • AnyOpenID – 为客户提供免费的解决scheme,网站商业

但是我不想依赖外部提供商,我也想要一个免费的解决scheme,所以我不受限于实施。

我也看到开发人员一个接一个地按照供应商的指示执行一项服务,并为所有事情build立模型和数据库表。

当然这会起作用,但它是一大堆工作,总是需要你的应用程序的发展和变化等。

我正在寻找的是一个抽象层 ,将所有的服务都集成到一个可以集成到我的网站的标准中。 一旦出现一个新的服务,我只想添加一个模型来处理那个特定提供者的抽象,这样我就可以无缝地把它集成到我的应用程序中。

或者更好的是,find一个已经可以下载的解决scheme。

理想情况下,这个抽象服务将独立于我的应用程序托pipe,因此可用于多个应用程序并独立升级。

上述三个解决scheme中的最后一个看起来很有希望。 一切都只是移植到一个合成的OpenID,而网站必须实现OpenID。

过了一会儿,我发现Django socialauth ,一个基于python的Django Web框架authentication系统。 但它看起来像上面描述的操作,我认为这是Stackoverflow使用(或至less一些修改后的叉…)相同的login系统。

我下载了它,试图设置它,看看它是否可以作为一个独立的解决scheme,但我没有运气,因为我不是很喜欢python。

我会喜欢基于PH​​P的解决scheme。

所以在这个长文本之后,我的问题恰恰是:

  • 你将如何实现SSO,比移植一切都有更好的想法,并以OpenID为基础?
  • 那有什么优点和缺点?
  • 你知道现有的解决scheme吗? 最好开源。

我希望这个问题不是太主观,先谢谢了。

更新:我的结论是,build立一个代理/包装或你可能称之为Facebook,将其移植到一个OpenID,所以它成为一个OpenID端点/提供者将是最好的select。 所以我就是这么做的。

请参阅下面的答案。

我添加了赏金来获得反馈/讨论。 Maby我的方法并不如我现在所想的那样好!

作为这个答案的原始作者,我想指出,我认为这是过时的 。 由于大多数提供商决定专门实施Oauth而不是Openid。 较新的OpenID服务也可能使用基于oauth的openid连接。 有很好的库,例如: https : //github.com/hybridauth/hybridauth

在讨论已有的答案之后,我总结:

几乎每个主要的提供商都是一个openid提供商/terminal,包括Google,Yahoo,Aol。

其中一些需要用户指定用户名来构buildopenid端点。 其中一些(上面提到的)确实具有发现URL,其中用户ID被自动返回以便用户只需要点击。 (如果有人能解释技术背景,我会很高兴)

然而,唯一的麻烦是Facebook,因为他们有他们的Facebook连接,他们使用OAuth的适应版本进行身份validation。

现在我为我的项目做的是build立一个openid提供程序,使用我的facebook应用程序的凭据对用户进行身份validation,以便用户连接到我的应用程序,并返回一个如下所示的用户标识:

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

我还将它configuration为获取电子邮件地址和名称,并将其作为AX属性返回。

所以我的网站只需要实施opend id,我很好:)

我build立在你可以在这里find的类: 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; } } 

它只是第一个工作版本(快速和肮脏)一些dynamic的东西硬编码到我的需要。 它应该显示如何和可以做到。 我很高兴如果有人拿起并改进它或重新写它或任何:)

那么我认为这个问题的答案

但是我加了一个赏金来讨论。 我想知道你对我的解决scheme的看法。

我将奖赏这个旁边的最佳答案/评论。

OpenID将是你最好的select这个应用程序。 它得到了许多供应商的支持:

  • 谷歌
  • 雅虎
  • 者myOpenID
  • AOL

唯一的问题是Twitter还没有实现OpenID。 这可能是因为他们是一个以公司为主的公司,所以他们想要自己的解决scheme。

为了解决这个问题,你可能会编写一个包装类来提供与OpenID的兼容性,但是即使你的用户没有Twitter账号,他们也可能有Facebook,Google或者Yahoo账号。

Facebook支持oauth,所以你必须将oauth移植到OpenID

一些用于OpenID的PHP库可以在这里find。

现在,有人提出了关于Facebook是oauth供应商的问题。

他们的oauthurl是“https://graph.facebook.com/oauth/authorize”;

如果你仍然不相信我,那么你可以看看这个 JavaScript文件,我得到的URL。 如果你不相信那个javascript文件,那么注意它是由stackexchange托pipe的,这个站点的提供者。 现在你必须相信。

快进了两年,“OpenID就是答案”的答案似乎正在被一些大的提供商甩在后面。 大多数主要的第三方整合网站似乎已经转向OAuth(通常OAuth2)。 此外,如果您不介意不使用OpenID / OAuth,则可以使用PHP编写完整的SSO解决scheme(免责声明和全面披露:本产品由CubicleSoft旗下自己开发和维护):

单点login服务器/客户端

当最初提出这个问题的时候,这是不存在的。 它具有自由许可证(MIT或LGPL),并符合您作为抽象层的要求。 这个项目往往是专注于企业login,但也有一些社交媒体(谷歌和脸书)。

您可能还想看看HybridAuth ,它只关注社交媒体login,但更多的是一个图书馆,而不是一个预先构build的解决scheme,您可以将其投入到服务器上并完成。 所以设置它需要多一点的工作。 这真的取决于你以后是什么。

如果您对OpenID解决scheme感到满意,那么很好,但是现在比两年前有更多select,而且人们仍然在寻找这个线索。