Session management controls HTTP session-related behavior including session fixation protection, concurrent session control, and session authentication strategy.
Strategy for handling session-related activity during authentication.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public interface SessionAuthenticationStrategy {
/**
* Performs session-related activity following authentication.
*
* @param authentication the authenticated user
* @param request the HTTP request
* @param response the HTTP response
* @throws SessionAuthenticationException if session handling fails
*/
void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response) throws SessionAuthenticationException;
}Protects against session fixation by changing the session ID.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public class ChangeSessionIdAuthenticationStrategy implements SessionAuthenticationStrategy {
public ChangeSessionIdAuthenticationStrategy();
/**
* Changes the session ID upon authentication.
*/
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response);
}Migrates session attributes to a new session to prevent session fixation.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public class SessionFixationProtectionStrategy implements SessionAuthenticationStrategy {
public SessionFixationProtectionStrategy();
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response);
/**
* Sets whether to migrate session attributes (default: true).
*/
public void setMigrateSessionAttributes(boolean migrateSessionAttributes);
}Controls concurrent session limits per user.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.session.SessionRegistry;
public class ConcurrentSessionControlAuthenticationStrategy
implements SessionAuthenticationStrategy {
/**
* Creates a concurrent session control strategy.
*
* @param sessionRegistry the session registry
*/
public ConcurrentSessionControlAuthenticationStrategy(SessionRegistry sessionRegistry);
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response) throws SessionAuthenticationException;
/**
* Sets the maximum number of sessions allowed (default: 1).
*/
public void setMaximumSessions(int maximumSessions);
/**
* Sets the session limit using SessionLimit interface.
*/
public void setMaximumSessions(SessionLimit sessionLimit);
/**
* Sets whether to throw exception when limit exceeded (default: false).
* If false, expires the least recently used session.
*/
public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded);
public void setMessageSource(MessageSource messageSource);
}Registers users with the SessionRegistry after authentication.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.session.SessionRegistry;
public class RegisterSessionAuthenticationStrategy implements SessionAuthenticationStrategy {
/**
* Creates a register session strategy.
*
* @param sessionRegistry the session registry
*/
public RegisterSessionAuthenticationStrategy(SessionRegistry sessionRegistry);
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response);
}Delegates to multiple session authentication strategies.
package org.springframework.security.web.authentication.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import org.springframework.security.core.Authentication;
public class CompositeSessionAuthenticationStrategy implements SessionAuthenticationStrategy {
/**
* Creates a composite strategy with multiple delegates.
*
* @param delegateStrategies the list of strategies
*/
public CompositeSessionAuthenticationStrategy(
List<SessionAuthenticationStrategy> delegateStrategies);
/**
* Invokes all delegate strategies in order.
* Short-circuits on any SessionAuthenticationException.
*/
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response) throws SessionAuthenticationException;
public String toString();
}Detects session authentication events and handles session-related behavior.
package org.springframework.security.web.session;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.web.filter.GenericFilterBean;
public class SessionManagementFilter extends GenericFilterBean {
/**
* Creates a session management filter.
*
* @param securityContextRepository the security context repository
* @param sessionAuthenticationStrategy the session strategy
*/
public SessionManagementFilter(SecurityContextRepository securityContextRepository,
SessionAuthenticationStrategy sessionAuthenticationStrategy);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
/**
* Sets the invalid session strategy.
*/
public void setInvalidSessionStrategy(InvalidSessionStrategy invalidSessionStrategy);
/**
* Sets the authentication failure handler.
*/
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler);
public void setTrustResolver(AuthenticationTrustResolver trustResolver);
}Handles invalid session detection.
package org.springframework.security.web.session;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public interface InvalidSessionStrategy {
/**
* Called when an invalid session is detected.
*
* @param request the HTTP request
* @param response the HTTP response
*/
void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
}Redirects to a URL when an invalid session is detected.
package org.springframework.security.web.session;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SimpleRedirectInvalidSessionStrategy implements InvalidSessionStrategy {
/**
* Creates a strategy that redirects to the given URL.
*
* @param invalidSessionUrl the URL to redirect to
*/
public SimpleRedirectInvalidSessionStrategy(String invalidSessionUrl);
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
/**
* Sets whether to create a new session (default: true).
*/
public void setCreateNewSession(boolean createNewSession);
}Represents the maximum number of sessions allowed.
package org.springframework.security.web.authentication.session;
import org.springframework.security.core.Authentication;
public interface SessionLimit {
/**
* Unlimited sessions constant (returns -1 to indicate no limit).
*/
SessionLimit UNLIMITED = (authentication) -> -1;
/**
* Returns the maximum sessions for the given authentication.
*
* @param authentication the authenticated user
* @return the maximum number of sessions
*/
int getMaximumSessions(Authentication authentication);
/**
* Creates a fixed session limit.
*
* @param maxSessions the maximum number of sessions
* @return a SessionLimit that always returns the given value
*/
static SessionLimit of(int maxSessions);
}Thrown when session authentication fails.
package org.springframework.security.web.authentication.session;
import org.springframework.security.core.AuthenticationException;
public class SessionAuthenticationException extends AuthenticationException {
public SessionAuthenticationException(String message);
public SessionAuthenticationException(String message, Throwable cause);
}Event indicating session ID was changed for session fixation protection.
package org.springframework.security.web.authentication.session;
import org.springframework.security.core.Authentication;
public class SessionFixationProtectionEvent extends AbstractSessionEvent {
/**
* Creates a session fixation protection event.
*
* @param authentication the authenticated user
* @param oldSessionId the old session ID
* @param newSessionId the new session ID
*/
public SessionFixationProtectionEvent(Authentication authentication,
String oldSessionId,
String newSessionId);
/**
* Returns the session ID before it was changed.
*/
public String getOldSessionId();
/**
* Returns the new session ID.
*/
public String getNewSessionId();
}Filter that monitors concurrent session usage and handles expired sessions.
package org.springframework.security.web.session;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import java.util.List;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.web.filter.GenericFilterBean;
public class ConcurrentSessionFilter extends GenericFilterBean {
/**
* Creates a concurrent session filter.
*
* @param sessionRegistry the session registry
* @param expiredSessionStrategy strategy for handling expired sessions
*/
public ConcurrentSessionFilter(SessionRegistry sessionRegistry,
SessionInformationExpiredStrategy expiredSessionStrategy);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
public void afterPropertiesSet();
/**
* Sets the SecurityContextHolderStrategy to use.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy);
/**
* Sets logout handlers to invoke on session expiration.
*/
public void setLogoutHandlers(LogoutHandler[] handlers);
public void setLogoutHandlers(List<LogoutHandler> handlers);
/**
* Sets the redirect strategy.
*/
public void setRedirectStrategy(RedirectStrategy redirectStrategy);
}Publishes session lifecycle events to the Spring application context.
package org.springframework.security.web.session;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
public class HttpSessionEventPublisher implements HttpSessionListener {
/**
* Publishes HttpSessionCreatedEvent when a session is created.
*/
public void sessionCreated(HttpSessionEvent event);
/**
* Publishes HttpSessionDestroyedEvent when a session is destroyed.
*/
public void sessionDestroyed(HttpSessionEvent event);
/**
* Publishes HttpSessionIdChangedEvent when session ID changes.
*/
public void sessionIdChanged(HttpSessionEvent event, String oldSessionId);
}Event published when an HTTP session is created.
package org.springframework.security.web.session;
import jakarta.servlet.http.HttpSession;
import org.springframework.context.ApplicationEvent;
public class HttpSessionCreatedEvent extends ApplicationEvent {
/**
* Creates a session created event.
*
* @param session the HTTP session that was created
*/
public HttpSessionCreatedEvent(HttpSession session);
/**
* Returns the HTTP session.
*/
public HttpSession getSession();
}Event published when an HTTP session is destroyed.
package org.springframework.security.web.session;
import jakarta.servlet.http.HttpSession;
import java.util.List;
import org.springframework.context.ApplicationEvent;
import org.springframework.security.core.context.SecurityContext;
public class HttpSessionDestroyedEvent extends ApplicationEvent {
/**
* Creates a session destroyed event.
*
* @param session the HTTP session that was destroyed
*/
public HttpSessionDestroyedEvent(HttpSession session);
/**
* Returns the HTTP session.
*/
public HttpSession getSession();
/**
* Returns the security contexts from the session.
*/
public List<SecurityContext> getSecurityContexts();
/**
* Returns the session ID.
*/
public String getId();
}Event published when an HTTP session ID changes (for session fixation protection).
package org.springframework.security.web.session;
import jakarta.servlet.http.HttpSession;
import org.springframework.context.ApplicationEvent;
public class HttpSessionIdChangedEvent extends ApplicationEvent {
/**
* Creates a session ID changed event.
*
* @param session the HTTP session
* @param oldSessionId the old session ID
*/
public HttpSessionIdChangedEvent(HttpSession session, String oldSessionId);
/**
* Returns the HTTP session.
*/
public HttpSession getSession();
/**
* Returns the old session ID.
*/
public String getOldSessionId();
/**
* Returns the new session ID.
*/
public String getNewSessionId();
}Disables URL encoding of session IDs to prevent session ID leakage.
package org.springframework.security.web.session;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.web.filter.OncePerRequestFilter;
public class DisableEncodeUrlFilter extends OncePerRequestFilter {
public DisableEncodeUrlFilter();
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException;
}Forces eager HTTP session creation to ensure session is available.
package org.springframework.security.web.session;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.web.filter.OncePerRequestFilter;
public class ForceEagerSessionCreationFilter extends OncePerRequestFilter {
public ForceEagerSessionCreationFilter();
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException;
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SessionConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.sessionManagement(session -> session
.sessionFixation().changeSessionId()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
);
return http.build();
}
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class ConcurrentSessionConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, SessionRegistry sessionRegistry)
throws Exception {
http
.sessionManagement(session -> session
.maximumSessions(2)
.expiredUrl("/session-expired")
.sessionRegistry(sessionRegistry)
);
return http.build();
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
}import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
public class CustomSessionStrategy implements SessionAuthenticationStrategy {
private final SessionRegistry sessionRegistry;
private final AuditLogger auditLogger;
public CustomSessionStrategy(SessionRegistry sessionRegistry, AuditLogger auditLogger) {
this.sessionRegistry = sessionRegistry;
this.auditLogger = auditLogger;
}
@Override
public void onAuthentication(Authentication authentication,
HttpServletRequest request,
HttpServletResponse response) {
// Log session creation
String username = authentication.getName();
String sessionId = request.getSession().getId();
String ipAddress = request.getRemoteAddr();
auditLogger.logSessionCreated(username, sessionId, ipAddress);
// Check for suspicious activity
List<SessionInformation> sessions =
sessionRegistry.getAllSessions(authentication.getPrincipal(), false);
if (sessions.size() > 5) {
auditLogger.logSuspiciousActivity(username,
"Excessive concurrent sessions: " + sessions.size());
}
}
}
// Configuration
@Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy(
SessionRegistry sessionRegistry,
AuditLogger auditLogger) {
return new CompositeSessionAuthenticationStrategy(Arrays.asList(
new ChangeSessionIdAuthenticationStrategy(),
new RegisterSessionAuthenticationStrategy(sessionRegistry),
new CustomSessionStrategy(sessionRegistry, auditLogger)
));
}import org.springframework.security.web.session.InvalidSessionStrategy;
public class CustomInvalidSessionStrategy implements InvalidSessionStrategy {
private final String redirectUrl;
public CustomInvalidSessionStrategy(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
@Override
public void onInvalidSessionDetected(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// For AJAX requests, return JSON
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"error\": \"Session expired\"}");
return;
}
// For regular requests, redirect
response.sendRedirect(request.getContextPath() + redirectUrl);
}
}
// Configuration
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.sessionManagement(session -> session
.invalidSessionStrategy(
new CustomInvalidSessionStrategy("/login?session=expired")
)
);
return http.build();
}