【问题标题】:Spring session for session sharing(clustering) between servers用于服务器之间会话共享(集群)的 Spring 会话
【发布时间】:2018-06-25 20:58:55
【问题描述】:

我试图让具有相同基域(子域不同)的两台机器共享会话。

spring-session-jdbc 似乎是我可以用来实现目标的解决方案。

当用户登录server-a 时,会话信息存储在 SPRING_SESSION 数据库中。
让我担心的是自定义org.springframework.security.core.userdetails.UserDetails 类也存储在该数据库中。

当server-b 尝试从数据库中读取会话数据时,它必须使用org.springframework.security.core.userdetails.UserDetails 的相同自定义子类。

所以我将与UserDetails 类相关的代码从server-a 复制到server-b。

我觉得这样做有点尴尬,因为 server-a 和 server-b 通常可能需要不同的 UserDetails。

这真的是使用 spring-session-jdbc 的预期方式吗?

另一个问题是,spring-security 是否必须同时用于 server-a 和 server-b?

【问题讨论】:

    标签: spring spring-security spring-session


    【解决方案1】:

    保持和加载会话的默认机制是通过SecurityContextRepository(Spring Security)或SessionRepository(Spring Session)。

    如果您使用 Redis 进行会话共享,则存储库实现可以是 RedisSecurityContextRepository (spring-security-redis) 或 RedisIndexedSessionRepository (Spring Session)。

    后一个肯定会序列化UserDetails,因此除非您使用相同的框架和用户类版本,否则您无法共享会话。

    我会使用自定义 SessionRepository 并将共享的用户信息存储在可移植的 Json 或 XML 或任何你喜欢的东西中,而不是 Java 对象序列化))

    【讨论】:

      【解决方案2】:

      根据Vedran Pavic's answer,听起来您应该使用 sso。也就是说,在某些情况下,不同的代码库可能希望共享相同的会话,例如在微服务集群中。在这种情况下,您应该简单地将您的 UserDetails 放入其他 jar/模块所依赖的基本 jar/模块中。您可以使用构建自动化工具使此打包更容易完成。

      要回答您的最后一个问题,如果这两个应用程序定期相互通信,那么我建议在任何地方都使用 Spring Security。

      【讨论】:

        【解决方案3】:

        Spring Session 旨在轻松启用会话集群,即让同一应用的多个实例共享外部会话存储,从而更轻松地扩展您的应用。

        对于您尝试解决的问题,使用适当的更高级别协议(例如 OAuth 2.0 和 OpenID Connect)并实施单点登录而不通过会话存储耦合您的应用程序可能是个好主意。

        虽然最初在不同应用之间共享会话存储的想法可能看起来很方便,但这种安排通常会带来很大的问题,正如您在 UserDetails 示例中所指出的那样。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-17
          • 2016-06-17
          • 1970-01-01
          • 2018-04-03
          • 2017-08-10
          • 2015-04-13
          • 1970-01-01
          相关资源
          最近更新 更多