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

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

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

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

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

First question :

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

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

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

Therefore, the main question :

现在,如果用户进入 example2.com 并且我们希望他使用他已经拥有的JWT令牌进行身份验证,流量应该是什么? Local Storage 不会't seem to allow cross-domain access so at this point the browser can' t读取JWT令牌以向 example2.com 发出请求!

应该 :

  • 用户是否会再次被重定向到 authentication server ?当用户对 example1.com 进行身份验证时, authentication server 可能已在用户上设置了cookie,因此 example2.com 的新身份验证请求可以使用该cookie来查看用户是否已经过身份验证并立即使用相同的JWT令牌将其重定向回 example2.com

  • 或者 example2.com 上的浏览器是否可以访问JWT令牌而无需再次转到 authentication server ?我看到有cross-storage solutions,但那些被广泛使用?它们是跨域SSO环境的建议解决方案吗?

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

回答(3)

3 years ago

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

3 years ago

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

但是,当在跨域之间使用此架构时 main drawback is that the user is going to be authenticated each time he navigates to other domain due to same-origin policy :会话令牌不能在域之间共享,因此SSO会将用户视为未经过身份验证 .

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

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

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

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

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

为了简化开发,我们最近发布了一个 cross domain SSO with JWT at https://github.com/Aralink/ssojwt

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

3 years ago

不确定这是否回答了您的问题,但如果您的主要目标是单点登录,我认为一个简单的reverse proxy将解决您的问题(至少是跨域存储问题) .

所以example1.com example2.com

会变得像

example.com/example1

example.com/example2

(从用户方面来说,这通常是清洁器)

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

如果这不是一个选项,你可能不得不求助于用户名pin,因为浏览器对跨域交互越来越严格 .