0

Good morning,

I am new to java and spring and currently have spring security implemented within one of my applications that uses the logout-url = /logout configuration along with a logoutSuccessHandler to allow users to click on a sign out button in order to log out. I have also implemented a heart beat pattern from the client side in javascript that will let the server know that the application is open in a browser. It post a message to the server every 5 minutes. If the browser is closed and the server does not receive a message from the browser that it is alive I want to force the logout-url to be called from the controller. How would I do this is java? I have tried to implement an HTTP request using HttpServletRequest but that does not seem to work.

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
  • Controllers are for managing HTTP requests. If you want to trigger behavior from something besides an HTTP request (eg: on a timer), you should probably be using your service layer to do the same workflow from something like an `@Scheduled` method, not adding the unnecessary overhead of firing off a real http request. – CollinD Oct 19 '18 at 14:42
  • Thank you. I will use a scheduled task , but the issue that I am having is programmatically invoking the spring security logout feature . It works fine when invoked from a form button or link on the client side that references the spring-security.xml config `logout-url=\logout'. Since spring handles all of the logic for invalidating the session, deleting the cookies & redirecting to the logout screen with a few configs I would like to invoke this from a class with the scheduler as opposed to having to rewrite the logic needed to handle it. Is it possible to invoke /logout from a class? – Adent User Oct 19 '18 at 19:01

3 Answers3

0

You may be approaching this from the wrong angle. It sounds like you want to set the maximum session timeout to be a value other than the default. Assuming you are running on a servlet container you can configure this in your web.xml guide.

If the user performs no activity with your server for the duration of the timeout period their session will expire.

If you need to perform an action on session destruction you can add an HttpSessionListener as described in link

Deadron
  • 5,135
  • 1
  • 16
  • 27
  • Thank you for the response, the issue with using session timeout is that in the applications current form even if a user is inactive data polling from other services make it seem as if they are. We are trying to add the heartbeat as a secondary check on the system to make sure that users who have closed there browser do not have active sessions. – Adent User Oct 19 '18 at 19:05
  • If you couple your session timeout timer to activity on only a single endpoint you are going to run into non trivial complexity issues. You will quire literally be building your own session management infrastructure on to of the existing container provided mechanism. Consider the affect on your other pages/endpoints, they will all have to repeatedly hit this endpoint as well. If someone loads your site with javascript disabled they will be evicted in an unreasonable time. – Deadron Oct 19 '18 at 20:35
0

You can go for Scheduler and that checks the value updated from the browser at specific intervals. And you can log out service locally. As CollinD mentioned you do not need a Httprequest. Good luck.

Nagaraja R
  • 39
  • 1
  • 5
  • Thank you. I will use a scheduled task , but the issue that I am having is programmatically invoking the spring security logout feature . It works fine when invoked from a form button or link on the client side that references the spring-security.xml config `logout-url=\logout'. Since spring handles all of the logic for invalidating the session, deleting the cookies & redirecting to the logout screen with a few configs I would like to invoke this from a class with the scheduler as opposed to having to rewrite the logic needed to handle it. Is it possible to invoke /logout from a class? – Adent User Oct 19 '18 at 19:01
0

This is a service that I created in the past to handle invalidating sessions forcibly and immediately when a user's access is removed.

@Service
public class SecurityServiceImpl implements SecurityService {
    private SessionRegistry sessionRegistry;

    @Autowired
    public SecurityServiceImpl(SessionRegistry sessionRegistry) {
        Assert.notNull(sessionRegistry, "This implementation of SecurityService requires a SessionRegistry");
        this.sessionRegistry = sessionRegistry;
    }

    @Override
    public Integer expireUserSessions(User user) {
        int result = 0;
        Set<SessionInformation> sessionsToDestroy = new HashSet<>();
        sessionRegistry.getAllPrincipals().forEach(principal -> {
            if (principal instanceof UserDetails) {
                UserDetails current = (UserDetails) principal;
                if (current.getUsername().equals(user.getEmail())) {
                    sessionsToDestroy.addAll(sessionRegistry.getAllSessions(current, false));
                }
            }
        });
        for (SessionInformation session : sessionsToDestroy) {
            result++;
            session.expireNow();
        }

        return result;
    }
}

Obviously the specific logic for selecting the session would be different since User is one of my entity classes.

CollinD
  • 7,304
  • 2
  • 22
  • 45