Java – How to make Spring Security store the HTTP Session in a database to use the web app on multiple servers

javasessionspring-security

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!

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?

Best Answer

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.

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/

In summary you need a configuration like this on your 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.

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:

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.

Related Topic