如何将Spring Security的会话信息存储在Redis中?

5

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

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

如果有任何文章和指针来实现相同的功能,请传递给我。

我正在考虑以下实现, 1) 对于每个成功的身份验证,将用户详细信息和会话详细信息存储在redis中。 这必须在UserDetailsService实现的loadUserByUsername()方法中实现 2) 当用户注销时,从redis中删除数据,我在哪里可以做这个操作?是否有任何Spring Security函数可以调用此操作? 3) 在应用程序重新启动时,从redis加载所有数据到Spring Security,我需要在哪里编写这个逻辑?

请让我知道是否我漏掉了任何信息。


这听起来像是你的容器应该处理的事情(如果你真的需要它),而不是Spring Security。例如,如果您适当地配置Tomcat将在重新启动时保留会话。 - Shaun the Sheep
@LukeTaylor 在SpringSecurity中有一个叫做PersistentTokenRepository的东西来存储令牌,这个能用于上述用例吗?此外,在Spring Security或Tomcat容器中执行操作会有什么不同? - Abdul Azeez
1
容器将持久化整个会话,因此用户可以在应用程序重新启动后继续之前的操作。Spring Security不能(也不应该)这样做,因为它不负责维护HttpSession。“记住我”在文档中有解释。通常情况下,当您不希望用户在数周甚至数月内必须重新登录时,您会使用它。它使用长期cookie,这是一个额外的安全风险,可能不合适。生命周期通常跨越许多容器会话。 - Shaun the Sheep
另外,你的应用程序实际上有多经常重新启动?你可能需要扩展你的问题,解释为什么你认为在应用程序重新启动后用户需要重新登录很重要。它真的经常发生吗?会不会有所不同?你的应用程序中的会话超时时间是多长? - Shaun the Sheep
4个回答

2

您只需要实现一个安全上下文存储的 SecurityContextRepository

  • 最终需要实现一个自定义过滤器来检索/存储会话信息(GenericFilterBean)

我认为可以仅给标准过滤器提供不同的存储库,但我并不确定,反正我需要自己实现...



1

您需要配置Spring Security的记住我(remember-me)功能。

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

更多信息请参阅Spring Security文档: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/remember-me.html

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


将“记住我”添加到应用程序并不是维护应用程序重新启动之间透明用户体验的好解决方案,这似乎是OP想要的。除非确实有单独的应用程序要求,否则可能不合适。 - Shaun the Sheep
@Luke:考虑这样一种情况,即您希望在部署期间保留活动用户的sessionId。例如,可以通过在Apache配置中切换活动容器(应用程序版本部署到单独的容器中)来推出代码部署。理想情况下,应用程序状态应该在容器切换之间持久存在,通过将sessionId持久化到后端(如Redis),然后可以通过引用sessionId获取其他持久化域对象。或者,在部署代码时提供连续的用户体验是否有更清晰的方法? - chris
@ norm,请参见我在评论中发布的有关Tomcat会话持久性的链接。应用程序状态不仅是会话ID,而且是整个序列化会话内容,因此它的平稳度取决于这些值是否与新部署的代码兼容。 - Shaun the Sheep
两年前的问题,使用记住我仍然是推荐的解决方案吗? - zengr

0
正如Luke Taylor所说,Tomcat的默认操作是在容器重启时对会话进行序列化/反序列化。 在这里
标准管理器的pathname属性是序列化文件的名称。如果您不指定路径名属性,则默认值为SESSIONS.SER。如果您不想在重新启动时恢复会话,则需要将其指定为空字符串值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接