Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 678
Jaxox Avatar asked Dec 10 '13 23:12

Jaxox


People also ask

Where does Spring Security store session?

Spring Security handles login and logout requests and stores information about the logged-in user in the HTTP session of the underlying webserver (Tomcat, Jetty, or Undertow). To track which session belongs to which client, the webserver sets a cookie with a random session id and stores the session object in memory.

How does Spring Security maintain session?

Session Fixation Protection With Spring Security By default, Spring Security has this protection enabled (“migrateSession“). On authentication, a new HTTP Session is created, the old one is invalidated and the attributes from the old session are copied over.

What is HTTP session spring?

Spring Session) is being used to manage the HTTP Session state. The HTTP Request count is simply incremented every time a client HTTP Request is made to the HTTP server (e.g. Servlet Container) before the HTTP Session expires.


2 Answers

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.

like image 114
gerrytan Avatar answered Oct 13 '22 02:10

gerrytan


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

like image 28
Yura Avatar answered Oct 13 '22 03:10

Yura