0

I have implemented Spring security in a Spring MVC web application. For the authentication purpose I am using LDAP and for authorization I am calling a third party Web Service that provides me All the authorizations and also a Session Id.

Once user log out or session timeout, I need to call the third party web service again with the same session Id for invalidation of session.

I have created a Log out Listener that listen to SessionDestroyedEvent like this

public class LogoutListener implements ApplicationListener<SessionDestroyedEvent>{
    private SecurityServiceHandler securityServiceHandler;

    @Override
    public void onApplicationEvent(SessionDestroyedEvent event) {
        SecurityContext securityContext = event.getSecurityContext();
        UserDetails ud=null;
        if(securityContext!=null){
             ud = (UserDetails) securityContext.getAuthentication().getPrincipal();


        if(securityServiceHandler==null){
            securityServiceHandler = new SecurityServiceHandler();
        }
        //String sessionId = securityServiceHandler.getSessionId();
        String sessionId = VirgoSessionManager.getSessionId();

        System.out.println(ud.getUsername());
        System.out.println(VirgoSessionManager.getSessionId());

        securityServiceHandler.invalidateSession(ud.getUsername(),sessionId);

        //reset the sessionId 
        securityServiceHandler.setSessionId(null);
        }

    }

I have used ThreadLocal in the VirgoSessionManager Class like follow

public class VirgoSessionManager {

    private static ThreadLocal<String> sessionId = new ThreadLocal<String>();

    public static String getSessionId(){

        return sessionId.get();
    }


    public static void setSessionId(String sId) {
        sessionId.set(sId);
    }

    public static void remove() {
        sessionId.remove();
    }
}

My problem is the that The VirgoSessionManager is not returning the session I have set during the Third party Session creation call after successful session cration even though I have implemented thread Local.

Any help will be appreciated. Thank you!

user2721314
  • 79
  • 2
  • 6

2 Answers2

0

you can have completely different thread serving your log out functionality which results in not having any value in ThreadLocal variable. For example tomcat uses thread pools so you need to be careful here. Try to log it/debug using Thread.currentThread().getName() and Thread.currentThread().getId() in getSessionId() and a place you set this value

hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
0

I fixed the issue with the separate thread calling the Logout/Session time out. I created a new customized User class and extended the Original spring "org.springframework.security.core.userdetails.User" class. I added new field "sessionId" to my customized user class.

So whenever I get the logged user details from Spring SecurityContext during logout/timeout, I will always have that sessionId and use to call invalidateSession method.

My customized user class looks like this.

package com.wvo.custom.security;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;


public class CustomUser extends User {

    private String virgoSessionId ;
    /**
     * 
     */

    private static final long serialVersionUID = 1L;

    public CustomUser(String username, String password,boolean enabled, boolean accountNonExpired, boolean accountNonLocked, boolean credentialsNonExpired,
            Collection<? extends GrantedAuthority> authorities) {
         super(username, password,enabled, accountNonExpired, accountNonLocked, credentialsNonExpired, authorities);
    }


    public String getVirgoSessionId() {
        return virgoSessionId;
    }

    public void setVirgoSessionId(String virgoSessionId) {
        this.virgoSessionId = virgoSessionId;
    }

}

Thank you !

user2721314
  • 79
  • 2
  • 6