Similar to xref:servlet/authentication/session-management.adoc#ns-concurrent-sessions[Servlet's Concurrent Sessions Control], Spring Security also provides support to limit the number of concurrent sessions a user can have in a Reactive application.
When you set up Concurrent Sessions Control in Spring Security, it monitors authentications carried out through Form Login, xref:reactive/oauth2/login/index.adoc[OAuth 2.0 Login], and HTTP Basic authentication by hooking into the way those authentication mechanisms handle authentication success.
More specifically, the session management DSL will add the {security-api-url}org/springframework/security/web/server/authentication/ConcurrentSessionControlServerAuthenticationSuccessHandler.html[ConcurrentSessionControlServerAuthenticationSuccessHandler] and the {security-api-url}org/springframework/security/web/server/authentication/RegisterSessionServerAuthenticationSuccessHandler.html[RegisterSessionServerAuthenticationSuccessHandler] to the list of `ServerAuthenticationSuccessHandler` used by the authentication filter.
The following sections contains examples of how to configure Concurrent Sessions Control.
* <<reactive-concurrent-sessions-control-limit,I want to limit the number of concurrent sessions a user can have>>
* <<concurrent-sessions-control-custom-strategy,I want to customize the strategy used when the maximum number of sessions is exceeded>>
* <<reactive-concurrent-sessions-control-specify-session-registry,I want to know how to specify a `ReactiveSessionRegistry`>>
* <<concurrent-sessions-control-sample,I want to see a sample application that uses Concurrent Sessions Control>>
* <<disabling-for-authentication-filters,I want to know how to disable it for some authentication filter>>
[[reactive-concurrent-sessions-control-limit]]
== Limiting Concurrent Sessions
By default, Spring Security will allow any number of concurrent sessions for a user.
To limit the number of concurrent sessions, you can use the `maximumSessions` DSL method:
Since the `maximumSessions` method accepts a `SessionLimit` interface, which in turn extends `Function<Authentication, Mono<Integer>>`, you can have a more complex logic to determine the maximum number of sessions based on the user's authentication:
.Configuring maximumSessions based on `Authentication`
When the maximum number of sessions is exceeded, by default, the least recently used session(s) will be expired.
If you want to change that behavior, you can <<concurrent-sessions-control-custom-strategy,customize the strategy used when the maximum number of sessions is exceeded>>.
The Concurrent Session Management is not aware if there is another session in some Identity Provider that you might use via xref:reactive/oauth2/login/index.adoc[OAuth 2 Login] for example.
If you also need to invalidate the session against the Identity Provider you must <<concurrent-sessions-control-custom-strategy,include your own implementation of `ServerMaximumSessionsExceededHandler`>>.
By default, when the maximum number of sessions is exceeded, the least recently used session(s) will be expired by using the {security-api-url}org/springframework/security/web/server/authentication/session/InvalidateLeastUsedMaximumSessionsExceededHandler.html[InvalidateLeastUsedMaximumSessionsExceededHandler].
Spring Security also provides another implementation that prevents the user from creating new sessions by using the {security-api-url}org/springframework/security/web/server/authentication/session/PreventLoginMaximumSessionsExceededHandler.html[PreventLoginMaximumSessionsExceededHandler].
If you want to use your own strategy, you can provide a different implementation of {security-api-url}org/springframework/security/web/server/authentication/session/ServerMaximumSessionsExceededHandler.html[ServerMaximumSessionsExceededHandler].
In order to keep track of the user's sessions, Spring Security uses a {security-api-url}org/springframework/security/core/session/ReactiveSessionRegistry.html[ReactiveSessionRegistry], and, every time a user logs in, their session information is saved.
Spring Security ships with {security-api-url}org/springframework/security/core/session/InMemoryReactiveSessionRegistry.html[InMemoryReactiveSessionRegistry] implementation of `ReactiveSessionRegistry`.
To do that, you can use the `ReactiveSessionRegistry` bean to retrieve all the user's sessions, invalidate them, and them remove them from the `WebSessionStore`:
By default, Concurrent Sessions Control will be configured automatically for Form Login, OAuth 2.0 Login, and HTTP Basic authentication as long as they do not specify an `ServerAuthenticationSuccessHandler` themselves.
For example, the following configuration will disable Concurrent Sessions Control for Form Login:
.Disabling Concurrent Sessions Control for Form Login
=== Adding Additional Success Handlers Without Disabling Concurrent Sessions Control
You can also include additional `ServerAuthenticationSuccessHandler` instances to the list of handlers used by the authentication filter without disabling Concurrent Sessions Control.
To do that you can use the `authenticationSuccessHandler(Consumer<List<ServerAuthenticationSuccessHandler>>)` method: