Java 如何让 Spring Security 将 HTTP 会话存储在数据库中以在多个服务器上使用 Web 应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20507749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:25:17  来源:igfitidea点击:

How can I make Spring Security store the HTTP Session in a database to use the web app on multiple servers?

javasessionspring-security

提问by Jaxox

Ok, I want my web app to be able to use HTTP sessions on multiple web servers. I can't use sticky sessions or session replication either!

好的,我希望我的 Web 应用程序能够在多个 Web 服务器上使用 HTTP 会话。我也不能使用粘性会话或会话复制!

What is the best practice for Spring Security to handle since Spring Security handles HTTP sessions already? Does Spring provide anything OOTB? Or does it have an option to store the session info to the database? SecurityContextPersistenceFilter?

由于 Spring Security 已经处理 HTTP 会话,因此 Spring Security 处理的最佳实践是什么?Spring 提供任何 OOTB 吗?或者它是否可以选择将会话信息存储到数据库?SecurityContextPersistenceFilter?

回答by gerrytan

You can configure your container to persist session to database using JDBC. If you use tomcat you can configure JDBC session persistence provider. I assume you can do similar thing on other containers too.

您可以将容器配置为使用 JDBC 将会话持久化到数据库。如果使用 tomcat,则可以配置 JDBC 会话持久性提供程序。我假设你也可以在其他容器上做类似的事情。

I've documented the steps on setting up tomcat JDBC session persistence on my blog: http://web.archive.org/web/20160417070959/http://gerrydevstory.com/2013/08/21/tomcat-7-jdbc-session-persistence/

我在我的博客上记录了设置 tomcat JDBC 会话持久性的步骤:http://web.archive.org/web/20160417070959/http: //gerrydevstory.com/2013/08/21/tomcat-7-jdbc -会话持久性/

In summary you need a configuration like this on your context.xml:

总之,您需要在 context.xml 上进行这样的配置:

<Manager className="org.apache.catalina.session.PersistentManager"
         maxIdleBackup="10">
  <Store className="org.apache.catalina.session.JDBCStore"
         connectionURL="jdbc:mysql://localhost/mytomcat?user=root"
         driverName="com.mysql.jdbc.Driver"
         sessionAppCol="app_name"
         sessionDataCol="session_data"
         sessionIdCol="session_id"
         sessionLastAccessedCol="last_access"
         sessionMaxInactiveCol="max_inactive"
         sessionTable="tomcat_sessions"
         sessionValidCol="valid_session" />
</Manager>

However, maxIdleBackup="10"above indicates session will be flushed into jdbc only after 10 seconds of inactivity. I don't know if setting it to 0 will work.

但是,maxIdleBackup="10"上面表示会话仅在 10 秒不活动后才会刷新到 jdbc。我不知道将它设置为 0 是否可行。

I imagine getting whole thing to work will be hard without sticky load balancer session, eg: how do you ensure session updates are flushed before the next request? You can't guarantee the next request will be served by the same node.

我想如果没有粘性负载平衡器会话,让整个事情工作将很困难,例如:您如何确保在下一个请求之前刷新会话更新?您不能保证下一个请求将由同一个节点提供服务。

Maybe another alternative is if you can hack your self / there's another session provider library out there that writes straight into database.

也许另一种选择是,如果您可以破解自己/还有另一个直接写入数据库的会话提供程序库。

Edit 21 May 2014:

2014 年 5 月 21 日编辑:

I just figured out hazelcast WM is a great library to do peer-to-peer session replication. All you need to do is include hazelcast jars to the classpath, setup hazelcast-wm as filter on your web.xml and configure hazelcast. It will automatically replicate session objects accross clusters.

我刚刚发现hazelcast WM 是一个很棒的库,可以进行点对点会话复制。您需要做的就是在类路径中包含hazelcast jar,在web.xml 上设置hazelcast-wm 作为过滤器并配置hazelcast。它将自动跨集群复制会话对象。

回答by Yura

looks like new spring project can do it easly https://docs.spring.io/spring-session/docs/current/reference/html5/

看起来新的 spring 项目可以轻松完成 https://docs.spring.io/spring-session/docs/current/reference/html5/