我在不同的网域中有多个网站:example.com
,example.org
,mail.example.com
和passport.example.org
。所有网站都具有共同的外观和感觉
应该共享相同的用户群。
在极端情况下,我仍然希望所有网站透明地(尽可能多) 使用以下关键属性共享用户会话:
单点登录。当用户在passport.example.org
登录并访问时
任何其他网站 - 他应该被视为登录。
登录用户在网站标题中获取“Hello,$username
”问候语并且不同
导航菜单,列出他们有权访问的服务。如果他没有登录,而是
问候语中有一个“登录”链接,指向passport.example.org/signon
。
可信域列表是已知的,因此实现起来也相当简单
使用OpenID或一些homebrewn轻量级协议。当用户第一次点击时
网站,我正在将他重定向到passport.example.org
的特殊身份验证端点,
然后默默地将他重新定向回来,带有身份信息(或“未登录”
匿名身份)包括在内。对于大多数浏览器,这是完全透明的
显然,我正在使用nonce值来对抗重定向循环。
单点注销。当用户点击任何网站标题中的“注销”时 下次他访问任何网站时 - 他应该被视为“不登录”。
OpenID不是为此而设计的。我目前的想法(我已经有了部分工作 实现)是发送不是用户身份,而是“全局”会话令牌和共享 DB中的全局会话表(global_session_token↔用户关系)。
机器人和无Cookie用户支持。网站有公共区域,应该 可由用户代理访问,无需任何cookie支持。
因此,我在(1)中提到的重定向成为一个问题,因为 每一页请求,我最终都会将用户代理投入到auth端点并返回。 这不仅会使机器人感到困惑,而且会污染我的会话数据库 很快就死了。我绝对不想显示“嘿, 你没有启用cookie,就走开!“页面,那是非常粗鲁的 令人失望的。虽然我需要cookie支持登录,但我希望用户可以自由阅读 网站的用途等等 - 没有任何限制。
我明确地不想要将会话ID放在URL中,除了一些透明的 我提到的跨域重定向。我认为这样做是一个安全问题 而且通常只是一件坏事。
在这里,我几乎没有想法。
好的,我知道这很难,但Google确实以某种方式(google.com
执行此操作,
google.
很多通用顶级域名,gmail.com
等等,对吧?所以这应该是
可能的。
我要感谢协议描述的想法(那是最好的)或链接 系统(要么是代码阅读,要么就是现场观看和学习) 成功实现了这样的事情。
总结一下:几个没有共同根域,共享用户群,单点登录,单点注销,匿名浏览无需cookie的域名。
所有网站都在同一个网络上(但在不同的服务器上),部分网站 共享相同的PostgreSQL数据库(在同一数据库的不同方案中休息)。 大多数站点都是用Python / Django编写的,但其中一些是使用PHP和Ruby on Rails。虽然我正在考虑与框架和语言无关的东西,但我很感激指向任何实现。即使我无法使用它们,如果我能理解它是如何完成的,那么我也许能够实现类似的东西。
答案 0 :(得分:31)
那么,让我再解释一下。 (所有网址都是虚构的!)正如我所说,访问者访问http://www.yourwebpage.com并表示他想要登录。他被重定向到http://your.loginpage.org?return=http://www.yourwebpage.com/Authenticated,他必须提供用户名和密码。
当他的帐户信息有效时,他将返回登录URL中提供的页面,但附加一个将用作ID的参数。因此,他前往http://www.yourwebpage.com/Authenticated?ID=SharedSecret,其中SharedSecret将是一个临时ID,有效期为30秒或更短
当您的身份验证页面被调用时,该页面将调用yourwebpage.com和loginpage.org之间共享的方法,以查找SharedSecret的帐户信息以检索更永久的ID。此永久ID存储在yourwebpage.com的网络会话中,不应向用户显示
共享方法可以是任何东西。如果两台服务器都在同一台机器上,则它们都可以访问同一个数据库。否则,他们可能会通过Web服务与另一台服务器通信。这将是服务器到服务器的通信,因此无论用户是机器人还是没有cookie支持都无关紧要。用户不会注意到这一部分
您唯一需要处理的是用户的会话。通常,将向用户发送存储在cookie中的会话ID,但它也可以作为GET请求的一部分作为URL的一部分。但是,通过在表单中添加隐藏的输入字段,将会话ID放在POST请求中会更安全一些。
幸运的是,一些Web开发语言已经提供了会话支持,因此您甚至不必担心维护会话和发送会话ID。不过,这项技术很有意思。您需要注意,会话应始终是临时的,因为会话ID被劫持的风险。
如果您必须处理不同域上的多个站点,那么您将需要首先进行一些服务器到服务器的通信。最简单的方法是让他们共享同一个数据库,但最好围绕这个数据库构建一个Web服务,以获得额外的保护。确保此Web服务仅接受来自您自己域的请求,以便添加更多保护
当您具有服务器到服务器的连接时,用户将能够在您的域之间切换,只要您将会话ID传递到新域,用户就会登录。如果用户正在使用cookie,会话丢失的可能性很小,需要再次登录。如果没有cookie,如果会话ID在浏览页面之间丢失,则用户可能必须再次登录才能获得新的cookie。 (例如,访问者访问Google,然后返回您的网站。使用Cookie,可以从Cookie中读取会话。如果没有Cookie,则会话会丢失,因为Google不会向前传递会话ID。<登记/>
请记住,在不同域之间传递会话ID存在安全风险。会话ID可能被劫持,从而使其他人可以冒充您的访问者。因此,会话ID应该是短暂的和混淆的。但即使黑客获得对会话ID的访问权限,他仍然无法完全访问该帐户本身。他将无法拦截服务器到服务器的通信,因此无法使用您的用户信息访问数据库,除非他直接进入登录页面。
答案 1 :(得分:5)
AFAIK,Google只为“Google.com”域名使用Cookie。但谷歌也使用OpenID,它允许通用的登录机制。基本上,这可以通过将您重定向到一个特殊的登录页面来实现。此登录页面将检测您是否已登录,如果您尚未登录,则会要求您登录。否则,它会直接将您重定向到下一页。
因此,在您的情况下,用户将打开somepage.example.com,此应用的会话没有登录ID。因此,它会将用户重定向到用户将登录的logon.example.biz。此页面后面也将是一个会话,该会话将告诉用户已经登录。(或者不是,在这种情况下,用户必须首先登录。)然后重定向用户somepage.example.com?sessionid=something这个sessionid将存储在somepage.example.com的会话中。然后,此会话还将知道用户已登录,对于用户来说,它几乎看起来是透明的。
实际上,用户被重定向两次。
答案 2 :(得分:1)
您使用的是ASP.NET吗?如果是这样,您可能需要查看enableCrossAppRedirects属性。
答案 3 :(得分:1)
如果您的所有应用程序都在一个域上,那么它并不太难,因为您可以使用域级cookie来处理会话控制。 (无Cookie会话管理很困难,但可以完成,但很难。)
但是,您在example.com域上指明了一些站点,在example.org域上指出了一些站点。
与我的google sigh-in和他们的orkut.com的其他网站玩一下,看起来当你点击需要凭据的页面时,它会将你重定向到一个公共站点进行帐户登录,然后重定向回来到原始站点,可能是在URL中传递某种会话令牌。据此,orkut.com服务器可能会直接与google.com服务器进行协商,以验证令牌并获取所需的任何其他用户信息。
有关域级Cookie的更多信息,需要
如果您有两个网站,例如foo.example.com
和bar.example.com,
,您可以设置特定于主机的Cookie,但您也可以为该网站设置一个cookie,域。
因此,foo.example.com
可以专门为foo.example.com
设置一个Cookie,它只会被自己看到,但它也可以为域example.com,
和用户设置一个cookie转到bar.example.com
他们也会看到第二个cookie。
但是,如果您还有一个网站snafu.example.org,
,则无法看到foo
设置的此域级Cookie,因为example.org
和example.com
是两个完全不同的域。
您可以使用域级Cookie来维护同一域中站点之间的会话信息。
如何设置域级cookie取决于您的开发环境(我没有使用rails的经验,抱歉)。
答案 4 :(得分:1)
对于此解决方案,不需要护照服务器。
登入
Cookie授权
退出
我不能尝试这个解决方案。但是现在我和你(SSO)有同样的问题,明天我会尝试这个。
答案 5 :(得分:0)
对于SSO场景和联合身份,我使用过shibboleth,但我认为你需要更简单的解决方案,如上所述。
答案 6 :(得分:-4)
支持跨域功能的rails插件可以实现这一目标。
我想这样做,我想到的唯一方法就是强迫用户下载工具栏,或者一些能够自动处理登录的小空中应用程序。
我很想知道另一种方式'因为打击