ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

第一个问题:

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

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

此外,如果 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 环境的建议解决方案吗?

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

您找到解决方案了吗?

r
rofrol

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

但是,当跨域使用此架构时,主要缺点是由于同源策略,用户每次导航到其他域时都会被重定向和验证:访问令牌不能共享域之间(example2.com 无法访问 example1.com 的数据),因此目标域会将用户视为未经身份验证,将他重定向到中央 SSO 服务。

为了防止身份验证服务重新请求凭据,通常有一个会话 cookie(不是访问令牌),但是有一种技术可以使用浏览器 localStorage/cookies 和指向中间域的 iframe 跨域共享数据{ 1}

认证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

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

此方法与 SSO 流完美兼容。这只是一种无需重定向即可共享身份验证令牌并在联合域时避免不必要的登录的方法


除了这种不遵守标准的解决方案之外,通常在跨域 SSO 中,一个跨域的 SSO 会跨越管理边界,在这种情况下,对两个域使用完全相同的 JWT 将使一个域中的应用程序所有者有可能冒充另一个域中的用户领域
谢谢@HansZ。我们实际上已经实施了这个解决方案,以便对具有数十个应用程序和相同用户的多个域进行单一管理。操作类似于google系统(相对而言)
我试过这个。对 sso.example.com 的调用会返回 cookie,但它不会保存在 sso.example.com 域的浏览器中。知道我会错过什么吗?
H
Hans Z.

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


但是因为它是 SSO,所以用户不必重新发送身份验证凭据(例如用户名/密码),对吗?那么它是如何完成的呢?身份验证服务器是否应在第一次为用户设置标准 cookie,以便在该用户从新域返回时自动对其进行身份验证?
但是,如果用户将浏览器配置为阻止所有 cookie 怎么办?
我想应该对 cookie 发出警告,“如果您的浏览器阻止 cookie,该网站可能无法正常工作”
单点登录并不一定意味着用户有一个由 cookie 跟踪的正在进行的会话:它的定义特征是对相同的身份提供者重复使用相同的凭据来访问不同的第 3 方应用程序,即不需要 cookie,只是重复使用相同的信用
@electrotype 是的,完全正确。必须在身份验证服务器上设置和显示 Cookie,因此用户将被识别、身份验证、令牌将自动颁发,并且用户将被重定向到第二个域而无需任何交互(无需询问凭据)
T
Tezra

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

所以 example1.com example2.com

会变成类似的东西

example.com/example1

example.com/example2

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

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

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