使用JWT进行跨域身份验证的单点登录流程

ele*_*ype 101 authentication single-sign-on jwt openid-connect

网上有很多关于使用JWT(Json Web Token)进行身份验证的信息.但是,在多域环境中使用JWT令牌作为单点登录解决方案时,我仍然没有找到明确的解释.

我在一家公司工作,该公司在不同的主机上有很多站点.我们使用example1.comexample2.com.我们需要一个单点登录解决方案,这意味着如果用户在example1.com上进行身份验证,我们希望他也可以自动在example2.com上进行身份验证.

使用OpenId Connect流程,我了解想要在example1.com上进行身份验证的用户将首先被重定向到身份验证服务器(或OP"OpenId Provider").用户在该服务器上进行身份验证,然后使用签名的JWT令牌将其重定向回原始example1.com站点.(我知道有另一个流程返回一个中间令牌,以后可以将其交换为真正的JWT令牌,但我不认为这对我们来说是必需的)...

所以现在用户回到example1.com并进行身份验证!他可以发出请求,在Authentication标头中传递JWT令牌,服务器能够验证签名的JWT,因此能够识别用户.太好了!

第一个问题:

如何将JWT令牌存储在客户端上?还有很多关于此的信息,人们似乎同意使用Web Storage是走的路而不是好的旧路cookies.我们希望JWT在浏览器重启之间保持一致,所以让我们使用Local Storage,而不是Session Storage......

现在用户可以重新启动他的浏览器,只要JWT令牌没有过期,他仍然会在example1.com上进行身份验证!

此外,如果example1.com需要向我们的另一个域发出Ajax请求,我理解配置CORS会允许这样做.但我们的主要用例不是跨域请求,它有一个单点登录解决方案!

因此,主要问题是:

现在,流程应该是什么,如果用户访问example2.com并且我们希望他使用他已经拥有的JWT令牌进行身份验证?Local Storage似乎不允许跨域访问,所以此时浏览器无法读取JWT令牌以向example2.com发出请求!

应该 :

  • 用户是否会再次重定向到身份验证服务器?当用户对example1.com进行身份验证时, 身份验证服务器可能已在用户上设置了cookie,因此example2.com的这个新身份验证请求可以使用该cookie来查看用户已经过身份验证并立即将其重定向回 example2.com使用相同的JWT令牌?
  • 或者,example2.com上的浏览器是否可以访问JWT令牌而无需再次访问身份验证服务器?我看到有跨存储解决方案,但是那些被广泛使用?它们是跨域SSO环境的建议解决方案吗?

我们不想要任何花哨的东西,我们会对最常用的解决方案感到满意!

ped*_*ofb 27

当用户未登录以请求凭据并发出新的身份验证令牌时,将用户重定向到中央身份验证服务是单点登录系统中使用oauth2或OpenIdConnect等众所周知的协议的常见方案

但是,当在跨域之间使用此架构时,主要缺点是每次由于同源策略导航到其他域时,用户将进行身份验证:会话令牌不能在域之间共享,因此SSO将会对待用户未经过身份验证.

example2.com无法访问数据,example1.com但有一个tecnique使用浏览器localStorage/cookies和指向中间域的iframe跨域共享数据sso.example.com

  1. 要对用户进行身份验证example1.com,将其重定向到身份验证服务器sso.example.com,请在身份验证后发出JWT并将其存储在此域的localStorage中.在此之后,将用户重定向到原始域example1.com

  2. example2.com指向时创建一个iframe sso.example.com.sso.example.com中的iframe读取JWT令牌并向父页面发送消息

  3. 父页面接收消息并获取附加的令牌继续SSO流程

同源策略没有问题,因为sso.example.com可以访问其localStorage,并且如果源和目标相互识别,则允许iframe与父页面之间的通信(请参阅http://blog.teamtreehouse.com/cross-domain-messaging - 后邮资)

为了简化开发,我们最近发布了一个带有JWT的跨域SSO,网址https://github.com/Aralink/ssojwt

此方法与SSO流完全兼容.它只是一种在没有重定向的情况下共享身份验证令牌的方法,可以在联合域时避免不必要的登录

  • 谢谢@HansZ.我们实际上已经实现了这个解决方案,以便对具有数十个应用程序和相同用户的多个域进行单一管理.该操作类似于谷歌系统(相对而言) (6认同)
  • 除了这个不遵守标准的解决方案,通常在跨域SSO中跨越管理边界,在这种情况下,对两个域使用完全相同的JWT将为一个域中的应用程序所有者打开在另一个域中模拟用户的可能性.域 (2认同)

Han*_* Z. 25

应该再次将用户重定向到身份验证服务器并获取新令牌(JWT),该令牌专门针对example2.com.这就是OpenID Connect和任何其他跨域联合SSO协议的工作原理.

  • 但是,如果用户不必重新发送身份验证凭据(例如用户名/密码),因为它是SSO,对吧?那怎么办?验证服务器是否应该第一次在用户上设置标准cookie,以便当该用户从新域返回时它可以自动验证他? (12认同)
  • 但是,如果用户将浏览器配置为阻止所有cookie,该怎么办? (6认同)
  • 我想应该对 cookie 发出警告,“如果您的浏览器阻止 cookie,该站点可能无法正常工作” (2认同)
  • 单点登录并不一定意味着用户有一个由 cookie 跟踪的持续会话:其定义特征是针对同一身份提供商重复使用相同的凭据来访问不同的第 3 方应用程序,即不需要 cookie,只需重复使用相同的信用 (2认同)

Tez*_*zra 6

不确定这是否回答了您的问题,但如果您的主要目标是单点登录,我认为简单的反向代理可以解决您的问题(至少是跨域存储问题)。

所以 example1.com example2.com

会变成类似的东西

example.com/example1

example.com/example2

(从用户方面来看,这通常更干净)

如果这不是一个选项,您可能必须进行设置,以便当用户在 1 个域中进行身份验证时,它也使用 AJAX/隐藏 iframe 来创建与其他域的身份验证(如果必须,请通过 url 发送 1 次令牌) )。

如果这不是一个选择,您可能不得不求助于用户名+密码,因为浏览器对跨域交互越来越严格。