使用JWT进行跨域身份validation的单点loginstream程

网上有很多关于使用JWT( Json Web Token )进行authentication的信息。 但是,在多域环境中使用JWT令牌进行单一login解决scheme时,我仍然没有find明确的解释。

我为一家在不同主机上有很多网站的公司工作。 我们使用example1.comexample2.com 。 我们需要一个单一的login解决scheme,这意味着如果用户在example1.com上进行身份validation,我们希望他也可以自动在example2.com上进行身份validation。

使用OpenId Connectstream程,我知道想要在example1.com上进行身份validation的用户将首先被redirect到身份validation服务器 (或OP :“OpenId Provider”)。 用户在该服务器上进行身份validation,然后使用签名的JWT令牌将其redirect回原始的example1.com站点。 (我知道还有一个stream程会返回一个中间标记 ,稍后它可以交换为真正的JWT标记,但我不认为这对我们是必需的)…

所以现在用户又回到了example1.com并通过身份validation! 他可以发出请求,将JWT令牌传递给Authentication头,服务器可以validation已签名的JWT,因此能够识别用户。 太好了!

第一个问题:

JWT令牌应该如何存储在客户端上? 还有很多关于这方面的信息,人们似乎认为使用Web Storage是一种好方法,而不是老式的cookies 。 我们希望JWT在浏览器重新启动之间保持持久性,因此我们使用Local Storage ,而不是Session Storage

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

另外,如果example1.com需要向我们的另一个域发出Ajax请求,我知道configurationCORS将允许。 但是我们的主要用例并不是跨域请求,它有一个单一的login解决scheme

所以主要的问题是:

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

应该 :

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

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

用户应该redirect到authentication服务器,并获得一个新的令牌(JWT),一个专门针对example2.com的令牌。 这就是OpenID Connect和任何其他跨域联合SSO协议的工作原理。

将用户redirect到中央身份validation服务时,如果用户没有login来请求凭据并发出新的身份validation令牌,则是使用众所周知的协议(如oauth2或OpenIdConnect)的Single Sign On系统中的常见scheme

然而,当在跨域中使用该模式时, 主要的缺点是,由于同源策略,每当他导航到其他域时,用户将要被authentication :会话令牌不能在域之间共享,所以SSO将会用户未经过身份validation。

example2.com无法访问example1.com数据,但是有一种技术可以使用浏览器localStorage / cookies和指向中间域的iframe来共享数据域sso.example.com

  1. 要在example1.com对用户进行身份validation,请将其redirect到sso.example.com的身份validation服务器, sso.example.com在身份validation后发出JWT,并将其存储在此域的localStorage中。 之后,将用户redirect到源域example1.com

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

  3. 父页面接收消息并获取连接的令牌继续SSOstream程

同源策略没有问题,因为sso.example.com可以访问其localStorage,并且iframe和父页面之间的通信是允许的,如果源和目的地相互识别(请参阅http://blog.teamtreehouse.com/跨域消息传递与postmessage

为了简化开发,我们最近https://github.com/Aralink/ssojwt上;发布了一个与JWT的跨域SSO

此方法与SSOstream程完全兼容。 这只是一种无需redirect而共享身份validation令牌的方法,并且可以避免在域联合时发生不必要的login

不知道这是否回答你的问题,但如果你的主要目标是单一login,我认为一个简单的反向代理将解决你的问题(至less跨域存储一个)。

所以example1.com example2.com

会变成类似的东西

example.com/example1

example.com/example2

(从用户方面来看,这通常是更清洁的)

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

如果这不是一个选项,你可能不得不诉诸用户名+ pin,因为浏览器越来越严格的跨域交互。