2

I'd like your help to get how implement this function: admin gets all logged in users using sessionRegistry.getAllPrincipals() and then can log off someone. I know how to log off current user (session.invalidate()), but have no idea how to force log out other users.

This code gets me all logged in users

public List<User> getAllLoggedInUsers() {
    List<Object> principals = sessionRegistry.getAllPrincipals();
    List<User> usersNamesList = new ArrayList<>();
    for (Object principal : principals) {
        if (principal instanceof org.springframework.security.core.userdetails.User) {
            usersNamesList.add(dao.findByLogin(((org.springframework.security.core.userdetails.User) principal).getUsername()));
        }
    }
    return usersNamesList;
}

Thanks a lot.

EDIT 1: I want next: admin chooses a user, bans it (change info in DB) and then if this user is active - log him off.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I guess, the simplest solution would be to restart the application server. This will kill all the sessions. – kk. Jun 04 '17 at 23:32
  • @KrishnaKuntala I don't need it) I just want to figure out the way how to implement this function. –  Jun 04 '17 at 23:34

2 Answers2

3

First, you need a sessionRegistry, this can get all sessions and register new session:

@Bean
SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();
}

Second, you need enable the sessionRegistry and use the ConcurrentSessionFilter to control the invalidate session.

http
 .sessionManagement() 
    .maximumSessions(-1)
    .sessionRegistry(sessionRegistry());

the -1 means no limit, BUT this will register the ConcurrentSessionFilter and RegisterSessionAuthenticationStrategy automatic. based the last spring security configuration, If you use xml or old version of spring security, please find this page for help.

ConcurrentSessionFilter will get the session from sessionRegistry, and will do logout when the session is expired.

The last thing is inject the same sessionRegistry bean to your application when try to get session by user and expire the user's session.

You can list a user’s sessions by calling the getAllSessions(Object principal, boolean includeExpiredSessions) method, which returns a list of SessionInformation objects. You can also expire a user’s session by calling expireNow() on a SessionInformation instance. When the user returns to the application, they will be prevented from proceeding.

chaoluo
  • 2,596
  • 1
  • 17
  • 29
  • 1
    Wow, that's was is more easier. I did not know sessionRegistry can provide all sessions. So I implemented that by myself. I created class SessionCounterListener that implements HttpSessionListener and every time session is created I add it to the list. So any time I can get the list of active sessions. –  Jun 05 '17 at 12:32
-2

suppose you try like this.

public void logoutUser(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
        Authentication auth = getAuthentication();

    for (int i = 0; i < logoutHandler.length; i++) {
        logoutHandler[i].logout(httpRequest, httpResponse, auth);
    }

        AnonymousAuthenticationToken aat = new AnonymousAuthenticationToken("your key you use",
                "anonymousUser", new GrantedAuthority[]{
                new GrantedAuthorityImpl("ROLE_ANONYMOUS")});
        ((SecurityContext)SecurityContextHolder.getContext()).setAuthentication(aat);
    }

Also you can find more approaches in following post1 and post2.

you can also get the current logged users and setSecurityContextHolder.getContext().setAuthentication(null)

Rajith Pemabandu
  • 616
  • 7
  • 14
  • 1
    Yea, that's the way to invalidate current active user session. But I need to invalidate not current but still active (logged in) user session. –  Jun 04 '17 at 23:39
  • @Paren'Vacya did mention that he knows how to log off the current user. – kk. Jun 04 '17 at 23:45