Thursday, December 27, 2012

Clustered Spring SessionRegistry: Spring Security Concurrent sessions in a clustered environment



I was recently working with a client whose application has a login module developed on spring security that was to be clustered using web sessions. The requirement was that if the user logs in twice into the system, the previous session should be invalidated and redirected to an error page. 
Spring security provides this functionality out of the box using ConcurrentSessionFilter. This filter makes use of an internal session registry that keep track of what users have logged in and their session details. 

However while integrating with Terracotta web sessions we found that this did not work. After investigation we found that the default session registry implementation was not clustered. I.e. it was creating local copies of session on each server. Thus the user was able to login multiple times.

In order to make this work the SessionRegistry work in a distributed environment or in front of a load balancer, we created a custom session registry on top of Ehcache. All the session details are now populated into Ehcache and get replicated across the servers. Hence a login session created on one server was now visible to the other servers and we could invalidate the previous session.

Attached project is tested on Terracotta 3.7.2, Jboss 7, Spring 3.0.5.

Download the code here.

4 comments:

  1. How does the session gets copied accross the servers by ehcache? I am not able to see it in your src codes, could you explain a little more? thanks.

    ReplyDelete
  2. @Jean: We use the Terracotta web session product to replicate sessions seamlessly across web servers. Read more about it here http://terracotta.org/documentation/web-sessions

    ReplyDelete
  3. Could you send the code me?I can't download.email:364105996@qq.com
    thank you

    ReplyDelete
  4. I saw in removeSessionInformation you did:
    SessionInformation info = getSessionInformation(sessionId);
    if (info != null) {
    logger.info("Removing session "+sessionId +" from session cache");
    info.expireNow();
    sessionIds.replace(new Element(sessionId, info));
    }
    So it not remove from sessionIds, it just expire,Is it wright. if so how can i remove it to sessionIds.
    I tried but it not working properly.
    Hope you reply soon.
    Thanks,
    Luan.
    Best Regards

    ReplyDelete