Spring security 如何在redis中存储spring安全会话信息?

Spring security 如何在redis中存储spring安全会话信息?,spring-security,redis,session-management,Spring Security,Redis,Session Management,我在应用程序中使用Spring security进行身份验证和授权。我使用Neo4j数据库作为后端,并实现userDetailsService进行身份验证 然而,每当我的应用程序重新启动时,用户都会被迫再次登录。 为了克服这个问题,我考虑将会话信息存储在redis数据库中,并在应用程序启动时将数据加载到Spring安全上下文中 如果有任何文章和指针可以实现,请转告 我正在考虑对其进行后续实施, 1) 对于每次成功的身份验证,请在redis中存储用户详细信息和会话详细信息。 这必须在UserDet

我在应用程序中使用Spring security进行身份验证和授权。我使用Neo4j数据库作为后端,并实现userDetailsService进行身份验证

然而,每当我的应用程序重新启动时,用户都会被迫再次登录。 为了克服这个问题,我考虑将会话信息存储在redis数据库中,并在应用程序启动时将数据加载到Spring安全上下文中

如果有任何文章和指针可以实现,请转告

我正在考虑对其进行后续实施, 1) 对于每次成功的身份验证,请在redis中存储用户详细信息和会话详细信息。 这必须在UserDetailsService实现的loadUserByUsername()方法中实现 2) 从redis中删除数据,当用户注销时,我在哪里可以获取这些信息?有没有任何spring安全函数可以调用 3) 每当应用程序重新启动时,将所有数据从redis加载到spring security,同样,我需要在哪里编写此逻辑


如果我遗漏了任何信息,请告诉我。

您需要配置Spring Security的“记住我”功能

记住我或持久登录身份验证指的是网站能够在会话之间记住主体的身份。这通常是通过向浏览器发送cookie来实现的,cookie在未来的会话中被检测到,并导致自动登录。springsecurity为这些操作提供了必要的挂钩,并有两个具体的memberme实现。一种使用哈希来保护基于cookie的令牌的安全性,另一种使用数据库或其他持久存储机制来存储生成的令牌

Spring安全文档中提供了更多信息:


您可以使用现成的实现或注入您自己的(前面提到的redis)。

正如Luke Taylor所说,Tomcat的默认操作是在容器重新启动时序列化/反序列化会话。

standard manager的pathname属性是序列化文件的名称。如果未指定路径名attirbute,则默认为SESSIONS.SER
如果您不希望在重新启动时恢复会话,则需要将其指定为空字符串值。

您需要做的就是实现

  • SecurityContextRepository,用于将安全上下文存储到
  • 最终是一个检索/存储会话信息的自定义筛选器(GenericFilterBean)

我认为可以给标准过滤器一个不同的存储库,但我不确定,反正我需要自己的实现…

redis中的存储会话现在是现成的功能


这听起来像是您的容器应该处理的事情(如果您真的需要的话),而不是Spring Security。例如,@LukeTaylor在SpringSecurity中有一种叫做PersistentTokenRepository的东西来存储令牌,可以用于上述用例吗。另外,在Spring Security或Tomcat容器中执行此操作有什么区别?容器将保持整个会话,因此用户可以在应用程序重新启动后像以前一样继续。SpringSecurity不能(也不应该)这样做,因为它不负责维护HttpSession。“记住我”在文档中有解释。当您不希望用户在数周甚至数月内重新登录时,您通常会使用它。它使用长期cookie,这是一个额外的安全风险,可能不合适。生命周期通常会跨越许多容器会话。另外,应用程序实际重启的频率是多少?您可能应该扩展您的问题,以解释为什么您认为在应用程序重新启动后用户必须再次登录很重要。这真的经常发生吗,这会带来不同?应用程序中的会话超时时间有多长?将“记住我”添加到应用程序中并不是在应用程序重启之间保持透明用户体验的好解决方案,而这似乎正是OP想要的。除非实际上有一个单独的应用程序要求,否则它可能不合适。@卢克:考虑在部署过程中希望保留活动用户的Session ID的情况。例如,可以通过切换Apache配置中的活动容器(将应用程序版本部署到单独的容器)来展开代码部署。理想情况下,应用程序状态应该在容器交换机之间持久化,通过在后端(如Redis)中持久化sessionId,这样就可以通过引用sessionId获取其他持久化域对象。或者,在部署代码的同时,有没有更干净的方法来提供连续的用户体验?@norm请参阅我在上面关于tomcat会话持久性的评论中发布的链接。应用程序状态不仅仅是会话ID,它是会话的整个序列化内容,因此它的顺利进行将取决于这些值是否与新部署的代码兼容。2年前的问题,使用RememberMe仍然是推荐的解决方案?