0

In our Spring Boot web server, I know how to limit the sessions per user (httpSecurity.sessionManagement().maximumSessions()), but I want to limit the total amount of sessions, to avoid load on the server.

How can this be done?

glytching
  • 44,936
  • 9
  • 114
  • 120
splintor
  • 9,924
  • 6
  • 74
  • 89
  • 2
    Load doesn't come from sessions. It comes from requests. All containers already have a thread pool limiting the number of concurrent requests. 2 people sending a request every 2 seconds cause a higher load than 30 people sending a request every minute (assuming all requests are equivalent) – JB Nizet Oct 25 '17 at 19:54
  • Possible duplicate of [spring limit max sessions ; limit max users](https://stackoverflow.com/questions/2106601/spring-limit-max-sessions-limit-max-users) and of [Spring Max Sessions on Application, NOT Max Sessions for a User on an Application](https://stackoverflow.com/questions/36722947) – splintor Oct 26 '17 at 05:57

1 Answers1

2

If 'total number of users' is a meaningful proxy for 'load' (see the comment from @JBNizet) in your system e.g. if most requests are ~identical in terms of resource footprint then you could define your own implementation of SessionAuthenticationStrategy. Here's a simple example:

private class AllUsersConcurrentSessionControlAuthenticationStrategy extends ConcurrentSessionControlAuthenticationStrategy {

    // probably inject this from application configuration
    private final int maxUsers;
    private final SessionRegistry sessionRegistry;

    public AllUsersConcurrentSessionControlAuthenticationStrategy(int maxUsers, SessionRegistry sessionRegistry) {
        super(sessionRegistry);
        this.maxUsers = maxUsers;
        this.sessionRegistry = sessionRegistry;
    }

    @Override
    public void onAuthentication(Authentication authentication, HttpServletRequest request,
                                 HttpServletResponse response) {
        if (sessionRegistry.getAllPrincipals().size() > maxUsers) {
            throw new SessionAuthenticationException("...");
        }
        super.onAuthentication(authentication, request, response);
    }
}

You register this like so:

http.sessionManagement().sessionAuthenticationStrategy(new AllUsersConcurrentSessionControlAuthenticationStrategy(maxUsers, sessionRegistry));

However, if 'total number of users' is not a meaningful proxy for 'load' then you should perhaps consider implementing your services in a non-blocking manner with each endpoint passing its request off to a threadpool and the request-to-threadpool allocation strategy could take into account how 'heavy' the request is. Lightweight requests could be handled by a large threadpool, heavyweitgh requests could be handled by a smaller threadpool.

glytching
  • 44,936
  • 9
  • 114
  • 120