gpt4 book ai didi

java - 如何使 Spring Security OAuth2 与负载均衡器一起工作?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:48:16 24 4
gpt4 key购买 nike

我们目前有 4 个 Spring 应用程序使用 Spring Security Oauth2 项目进行身份验证。这些应用程序是 REST API,由我工作的公司中的其他内部应用程序使用。

由于我们没有进行负载平衡,因此在开发和 QA 环境中一切正常,但现在我们处于预生产阶段,我们面临着负载平衡器 (LB) 的问题。

这是这个问题的工作流程:

  1. 客户端发送对 oauth token 的请求
  2. LB 将请求重定向到 Box 1
  3. Box 1 验证并返回有效的 Bearer Token
  4. 客户端接收 token 并存储它以供在 session 中使用
  5. 客户端在 REST API 中发送服务请求,将之前检索到的 token 添加到 header 中
  6. LB 将请求重定向到 Box 2
  7. Box 2 无法通过身份验证,因为它无法识别 token 并返回无效凭证响应

我们正在使用内存中的用户存储:

<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />

有没有办法让不同的box共享同一个token store?我知道有一个 JdbcTokenStore 可用于将 token 持久保存到数据库,但我更愿意避免持久 token ,因为这些应用程序指向仅存储业务信息的遗留数据库。

最佳答案

我问这个问题有点晚了,但也许这会帮助寻找类似答案的人。在负载均衡器上使用多个 oauth 服务器时,您需要注意两件主要事情:

正如@chris-h 在他的回答中提到的那样,您需要确保任何其他 oauth 服务器都可以读取(和信任)支持由任何 oauth 服务器发布的访问 token 的信息。您可以按照他的建议使用 JDBC token 存储,但这有一个缺点,即如果服务器 A 必须验证服务器 B 颁发的访问 token ,它总是必须访问数据库才能这样做。

更好的解决方案 (IMO) 是使用 JWT 访问 token ,其中验证 token 所需的所有信息都在其中加密。只要所有 oauth 服务器使用相同的加密 key ,它们就可以读取彼此访问 token 中的数据,并相信数据是有效的,因为它是加密的。优点是不需要数据库调用来验证访问 token 。缺点是一旦访问 token 被颁发,就没有简单的方法使它失效。如果您想知道为什么在可以增加访问 token 本身的过期时间时需要刷新 token ,这就是最大的原因。

要注意的第二件事是 Spring oauth 实现使用 session 来跟踪用户在身份验证过程中的位置。如果您不小心,您可能会陷入“无限循环”的境地。假设您有两个 oauth 服务器——服务器 A 和服务器 B:

  1. 用户转到需要身份验证的网页或服务,因此被重定向到“foo.com/oauth/authorize”。负载均衡器将此请求发送到服务器 A。
  2. 由于服务器 A 没有任何证明用户已经通过身份验证的 session 信息,它会将用户重定向到位于 foo.com/oauth/login 的登录页面。重定向通过负载均衡器返回,由于负载均衡器以“循环”方式工作,这次它将请求发送到服务器 B。
  3. 用户成功登录,因此写入 session 信息以跟踪这一点。 此 session 信息只有服务器 B 知道
  4. 由于登录成功,用户被重定向回“foo.com/oauth/authorize”以继续身份验证过程。重定向再次通过负载均衡器返回。由于负载均衡器以“循环”方式工作,这次它将请求发送到服务器 A。但是服务器 A 不知道服务器 B 上发生的成功登录。返回步骤 2!<

这个问题的最佳(当前)解决方案可能是确保您的负载平衡器支持“粘性 session ”——也就是说,一旦它将特定用户发送到服务器 A 或服务器 B,它总是将该用户发送到同一台服务器一段时间。

更好的解决方案可能是让 oauth 实现完全不使用 session 。相反,使用作为参数传递给/oauth/* 的加密数据表示您在登录过程中的位置。与 JWT token 的工作方式类似,如果所有服务器都共享加密 key ,则信息可以被所有服务器信任。

关于java - 如何使 Spring Security OAuth2 与负载均衡器一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18836427/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com