我们如何访问应用服务器中的身份验证服务器提供的 cookie?

问题描述

我正在阅读其官方网站上的 angular (https://blog.angular-university.io/angular-jwt-authentication/) 博客,其中使用单独的服务器进行身份验证,并使用不同的服务器进行应用程序。因此,在这种情况下,cookie 将由身份验证服务器发出,但将在应用程序服务器中使用。这怎么可能?我无法理解该博客的以下解释:

Cookie 和第三方身份验证提供商

在 cookie 中接收会话 JWT 的一个潜在问题是我们无法从处理身份验证逻辑的第三方网络域接收它。

这是因为在 app.example.com 上运行的应用程序无法访问来自其他域(如 security-provider.com)的 cookie。

因此,在这种情况下,我们将无法访问包含 JWT 的 cookie,并将其发送到我们的服务器进行验证,从而无法使用 cookie。

我们能否从这两种解决方案中获得最佳效果

第三方身份验证提供商可能允许我们在我们网站的可配置子域(例如 login.example.com)中运行外部托管的登录页面

因此,可以将所有这些解决方案的最佳组合结合起来。解决方案如下:

  • 在我们自己的子域 login.example.com 上运行的外部托管登录页面,以及在 example.com 上运行的应用程序
  • 页面设置了一个包含 JWT 的 HTTP Only 和 Secure Cookie,为我们提供了良好的保护,以防止依赖于窃取用户身份的多种类型的 XSS 攻击
  • 此外,我们还需要添加一些 XSRF 防御,但对此有一些易于理解的解决方案。

有人请解释以下行:

第三方身份验证提供商可能允许我们在我们网站的可配置子域(例如 login.example.com)中运行外部托管的登录页面

这是什么意思,我们如何在认证服务器上实现这一点,我们如何在应用服务器中访问认证服务器发出的cookie。 请说明是指在认证服务器发出的cookie中将域字段设置为应用服务器,还是其他。

Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

此外,如果是这种情况,应用服务器如何验证身份验证服务器提供的 cookie。身份验证服务器是否也将此 cookie 发送到应用程序服务器?我们是否也必须将这种机制落实到位?

解决方法

你的问题对我来说有点模糊,有很多不同的问题。

这是因为在 app.example.com 上运行的应用程序无法访问来自其他域(如 security-provider.com)的 cookie。

Cookie 仅发送到它们来自的域。因此,两个不同域上的两个应用程序无法访问彼此的 cookie。

第三方身份验证提供商可能允许我们在我们网站的可配置子域(例如 login.example.com)中运行外部托管的登录页面。

此问题的解决方案是使用子域将两个应用程序放在同一个域中。 app.com 和 login.com 无法访问彼此的 cookie。 app.example.com 和 login.example.com 可以,因为它们都在域 example.com

例如,oauth 还使用了其他解决方案。我会总结一下它的工作原理,但我建议你自己查看细节。

假设我们有 app.com 和 login.com。

  1. 用户访问 app.com 并且未登录。用户点击登录按钮。
  2. 用户被重定向到 login.com?application=app.com
  3. 用户使用其凭据登录
  4. login.com 通过 URL 中的会话将用户重定向回 app.com:app.com?session=123
  5. app.com 可以使用 sessionid 从 login.com 获取有关用户的信息
,

正如 Robin 正确指出的那样,使用子域是一种处理同源/CORS 策略的方法。 这可能不适用于所有场景 - 例如,在我的情况下,我们希望使用 AD 公司帐户来验证用户,而不必创建其他帐户。 再加上一些额外的好处,比如将用户管理与应用程序分开。对于使用 MS Azure 的 AD 用户,您可以执行此操作,它的工作原理与转发和重定向的描述基本相同。在我们的例子中,我们将 JWT 承载令牌放在 HTTP 标头中并且不使用 cookie。 后端通过每个 REST 请求获取 HTTP 标头中的 JWT 令牌,并可以通过使用身份验证提供程序的公钥对其进行解密来验证它。 Token 可以携带除用户 ID 之外的其他信息,如友好名称、电子邮件或用于后端授权的用户角色。整个过程花费了我们一些时间来实现,这不是一项微不足道的任务,即使您使用第三方提供商而不是您自己的 OAuth 实例也是如此。

,

为了补充其他 2 个(正确)答案,域之间无法共享 cookie 的原因有几个。它们都归结为相同的问题:内部数据是私有的,如果不强制执行,那么登录的安全性将大大降低。任何人都可以编写一个简单的脚本,不仅可以访问 jwt 令牌,还可以访问用户数据。另一个原因是因为用户只允许第一个域拥有其中的用户数据数据。

,

有3个核心概念:

  1. app.example.com 无法读取 security-provider.com 域的 cookie。安全限制。
  2. 您无法通过 js 读取 HttpOnly cookie。
  3. 由于 #1 和 #2,您需要在同一个域上实现代理应用程序。

简单地说,他们告诉您的是在您的 sub.mydomain 上创建一个新的仅登录页面,并在 mydomain 上与主应用程序通信,如在 sub.mydomain 上设置 cookie domain=mydomain 可在 mydomain 和 XSRF 上访问,反之亦然。

一篇关于我们在 2015 年如何处理跨域通信的简短文章, might be interesting to read