Spring 在数据库中存储表单登录会话

Spring 在数据库中存储表单登录会话,spring,tomcat,spring-security,Spring,Tomcat,Spring Security,我的Spring服务器上的安全上下文使用Spring security的内置表单登录实现。目前,登录会话由servlet容器本地存储在内存中。我想用我的一个Spring Data Mongo存储库来取代HttpSessions的存储和检索方式。我在Java配置中寻找了一个用于会话管理的“插槽”,但没有找到任何东西。明确地说,我要找的是相当于a的,但是会话 以下是我的安全配置类中Java配置的相关片段: ... .sessionManagement() .sessionCreationPo

我的Spring服务器上的安全上下文使用Spring security的内置表单登录实现。目前,登录会话由servlet容器本地存储在内存中。我想用我的一个Spring Data Mongo存储库来取代HttpSessions的存储和检索方式。我在Java配置中寻找了一个用于会话管理的“插槽”,但没有找到任何东西。明确地说,我要找的是相当于a的,但是会话

以下是我的安全配置类中Java配置的相关片段:

...
.sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
    .and()
.formlogin()
    .loginProcessingUrl("/authentication/login")
    .successHandler(successHandler)
    .usernameParameter("username")
    .passwordParameter("password")
    .failureUrl("/login?error")
    .loginPage("/login")
    .and()
.logout()
    .logoutUrl("/authentication/logout")
    .deleteCookies("JSESSIONID")
    .invalidateHttpSession(true)
    .logoutSuccessUrl("/login")
    .and()
...
据我所知,我没有做任何特别奇怪的事。这可能与此无关,但我想确切地说明,当我说找不到正确的配置插槽时,我在看什么

我仔细查看了的源代码,它似乎是SpringSecurity的过滤器链中负责检索和存储HttpSessions的过滤器。它将会话检索委托给中的调用
getSession()
,将会话存储委托给中的调用
saveContext()

为了正确地替换默认的服务器本地会话存储机制,我看到了三种方法

  • 将Spring数据备份安全上下文存储库插入持久性过滤器。然后,包装传入请求以实现查询自定义安全上下文存储库而不是本地存储的自定义
    getSession()
    行为。然后,内置的持久性过滤器将“做正确的事情”

  • 设置以使用自定义SecurityContextPersistenceFilter替换默认筛选器,该筛选器直接使用my Spring数据存储库,而不是调用
    getSession()
    或使用安全上下文存储库。事实上,我以前从未使用过对象后处理器,所以如果这不是它们的用途,请告诉我

  • 最后一个选择不是我正在考虑的,但值得一提。我认为,在所有的魔力之下,Spring安全性实际上是委托给servlet容器实现会话存储。因此,将备份存储更改为Mongo的一种方法是使用类似Tomcat的管理器接口的东西来定制会话持久性行为。这不是我想做的事情,因为它与Spring变得非常分离,我失去了通过依赖注入使用我的服务的能力,它完全依赖于容器,这使得很难随心所欲地进行更改


  • 我确信清除会话存储并用数据库替换它是Spring服务器的一个相当常见的需求。通常是怎么做的?如果我只是缺少一个配置选项,我想看看它的位置。否则,我要找的就是关于选择哪条路线(以及为什么)的建议。

    spring3
    中,这个地方就在那里

    基本上,您可以定义会话过滤器并专门指定会话策略或会话注册表

    会话注册表负责处理会话失效和创建。在这一点上,你可以坚持你需要坚持的任何东西

    这种方法的缺点是,它要求您在
    web.xml
    文件中声明会话事件发布者,或者处理一切

    一个例子是实现
    SessionRegistry
    SessionAuthenticationStrategy
    。从那里,当用户进行身份验证或执行
    getSession(true)
    (或使其无效)时,它将到达代码,您可以在那里对其进行操作。您的策略将注入会话注册表。如果用户通过身份验证链进行身份验证,它将到达您的策略,该策略将会话传递到您的注册表

    另一种方法是添加自己的自定义过滤器。扩展
    GenericFilterBean
    的类。然后注册:

    <security:custom-filter ref="customSessionFilter" after="LAST" />
    
    
    

    在本例中,它将最后执行。这很有用,因为您可以检查活动会话或成功通过身份验证的用户。

    类似于选项3的方法(不依赖特定于容器的接口)将与MongoDB支持的实现一起使用


    这将处理持久化所有HTTP会话数据,而不仅仅是Spring security特有的位。

    您能再具体一点吗?当你说“会话筛选器”时,你想到了哪个筛选器类?文档建议添加ConcurrencySessionControlFilter,以防止主体对同一应用程序的并发身份验证次数超过指定次数。我对管理并发会话不感兴趣。您是否建议使用此筛选器的会话注册表自定义会话持久性,而我应该忽略建议的使用?我将继续尝试,下次有机会尝试。如果它确实允许我插入Spring数据存储库进行会话存储,我将立即接受它。首先要确保它工作正常。这确实是会话持久性配置缺少的“插槽”。非常感谢。