网上有很多关于使用JWT( Json Web Token
)进行身份验证的信息 . 但是,在多域环境中使用JWT令牌作为单点登录解决方案时,我仍然没有找到明确的解释 .
我在一家公司工作,该公司在不同的主机上有很多站点 . 我们使用 example1.com 和 example2.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 回答
应该再次将用户重定向到身份验证服务器并获取新令牌(JWT),该令牌专门针对example2.com . 这就是OpenID Connect和任何其他跨域联合SSO协议的工作原理 .
当用户未登录以请求凭据并发出新的身份验证令牌时,将用户重定向到中央身份验证服务是单点登录系统中使用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流完全兼容 . 它只是一种在没有重定向的情况下共享身份验证令牌的方法,可以在联合域时避免不必要的登录
不确定这是否回答了您的问题,但如果您的主要目标是单点登录,我认为一个简单的reverse proxy将解决您的问题(至少是跨域存储问题) .
所以example1.com example2.com
会变得像
example.com/example1
example.com/example2
(从用户方面来说,这通常是清洁器)
如果这不是一个选项,您可能必须进行设置,以便当用户在1个域中进行身份验证时,它使用AJAX /隐藏的iframe来创建与其他域的身份验证(如果必须,则通过URL发送1次令牌) ) .
如果这不是一个选项,你可能不得不求助于用户名pin,因为浏览器对跨域交互越来越严格 .