跨域登录 - 如何在从一个域转移到另一个域时自动登录用户

61

我们提供许多在线服务。我们需要开发一个系统,当用户从一个服务(domain1.com)转移到另一个服务(domain2.com)时,为其提供快速/简单的体验。

有没有一种安全可靠的方式,在用户被传输到新服务之后自动登录用户?

如果下面的解决方案完全不安全/错误,请告诉我。

我们考虑采用类似于许多在线服务提供的密码恢复系统的系统-发送包含唯一哈希值的链接给用户,并在链接过期后允许他们更改密码。

domain1.com网站将生成一个唯一哈希值并将其存储在与哈希值相关联的用户和过期日期时间字段链接到的数据库中。

用户将被传输到domain2.com/auto/?hash=d41d8cd98f00b204e9800998ecf8427e

domain2.com接下来会向domain1.com请求哈希值以获取有关用户的信息。domain1.com然后将从数据库中删除哈希值。domain2.com将登录用户并设置Cookie等。

基于OpenID或OAuth的系统能否实现相同的结果?

5个回答

147
单点登录(SSO)的概念非常简单。
  • 用户进入domain1.com
  • domain1.com检查到没有会话cookie。
  • domain1.com重定向到sso.com
  • sso.com呈现登录页面并获取凭据。
  • sso.com为用户设置会话cookie。
  • sso.com然后重定向回domain1,到一个特殊的URL(如domain1.com/ssologin)。
  • ssologin URL包含由sso.com“签名”的参数。它可以是使用共享密钥加密loginid的base64字符串,也可以是其他形式。
  • domain1.com接收到加密令牌后,解密它并使用新的登录ID来登录用户。
  • domain1为用户设置会话cookie。

下面是另一个例子:

  • 用户进入 domain2.com,它跟随 domain1 并重定向到 sso.com
  • sso.com已经有了用户的 cookie,所以不需要呈现登录页面。
  • sso.com使用加密信息重定向回 domain2.com
  • domain2.com登录用户。
这就是它的基本原理。您可以使其更加稳健、功能更加丰富(例如,这是SSOn,而不是SSOff,用户可以从domain1“注销”,但仍然登录到domain2)。您可以使用公钥对凭据进行签名,可以发送请求以传输更多信息(如授权权限等)从SSO服务器。您还可以有更密切的集成,例如定期检查域是否仍具有来自SSO服务器的权限。
但是,通过浏览器使用重定向的cookie握手是所有这些SSO解决方案所基于的关键基础。

4
注意ssologin链接中的"signed"参数。如果您的参数不包含nonce /时间戳,捕获查询字符串的某人将能够使用它进行登录。全部使用SSL将有助于缓解此问题。 - russau
@russau 我打算实现这个方法,但是在设置nonce时遇到了一些困难,我应该把它存储在哪里? - albanx
@albanx Nonce是请求的一部分。您可以使用Nonce来检查请求的有效性。例如,Nonce设置为当前时间的格林威治标准时间(GMT),当服务器获得它时,可以将Nonce时间与当前时间进行比较。如果超过了1分钟,就可以拒绝该请求。但是,请勿在请求中以纯文本形式添加Nonce。 - Will Hartung
@WillHartung 我在这里找到了一个有效的nonce实现 https://dev59.com/Km855IYBdhLWcg3wynmC - albanx
  1. 我们应该在 domain2.com 请求到 sso.com 中使用 JWT 令牌吗?
  2. 如果 sso.com 没有用户的 cookie,因此呈现登录页面,我们最终会有 3 次重定向(一次到 sso.com,一次到 sso.com 登录,一次到 domain2.com 登录页面)吗?
  3. 我们可以使用另一个 JWT 令牌,这次是由 sso.com 发行的,以授予对 domain2.com 的登录访问权限吗?
- Stephane
显示剩余2条评论

8
如果有人能够进行中间人攻击并获取到该哈希值,他们是否能够窃取跨域传输?显然,它需要在客户端需要使用之前生成并发送给客户端。例如:
我正在进行中间人攻击,监视杰克。 杰克访问domain1.com,这会导致准备一个哈希值并将其发送给他,以便当他访问domain2.com时,他可以将该哈希值作为身份验证发送。 当他访问domain1.com时,他的请求通过我传递,你返回页面,我获取哈希值并让他继续。 我使用哈希值访问domain2.com,现在你已经让我进入了domain2.com并删除了哈希值。 除非他尝试登录到domain2.com并被告知他的凭据无效,否则他不会察觉到任何异常。
如何解决这个问题?

7
使用SSL,如果Jack验证了domain1.com服务器并建立了保密通道,那么您将无法进行中间人攻击。 - erickson
好的观点。理论上来说,这应该意味着只要他们使用SSL,OP的模型应该是相当安全的。 - BenAlabaster

7

如果你只在跨域登录时使用SSL,而不是在整个会话中使用SSL,则使用SSL没有任何意义。窃取会话cookie与在url中使用哈希值一样容易。如果会话的其余部分不安全,那么在SSL中隐藏哈希值有什么意义。

顶部给出的方法基本上是标准方法。选择是否使用安全协议是另一回事,但仅加密会话的一部分是毫无意义的。


6

这是一个不错的解决方案。以下有两点需要考虑:

您使用了“哈希”一词,但不清楚要对哪些数据进行哈希。相反,使用“nonce”:由加密质量RNG生成的大型(128位)数字。

此外,您没有指定,但用户与两个域之间以及域之间的通信必须是安全的。使用SSL来验证服务器并保持nonce机密。


2

关于SEO怎么处理? 似乎每个成功登录之前的请求都会被重定向到其他域名并返回。 我觉得这很丑陋。 你应该发送什么头信息?301到SSO,然后再返回301到原始页面吗?这样搜索引擎爬虫就需要对那个页面进行两次索引更新了吗?


重定向到SSO应该是结束 - 如果您不登录,则不会被重定向回来。 - Skip Head

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接