Spring Security Web module provides comprehensive security services and servlet integration for web applications built with the Spring Framework
Logout handling manages user logout operations, clearing security contexts and invalidating sessions.
Interface for participating in logout operations.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public interface LogoutHandler {
/**
* Called to perform logout operations.
*
* @param request the HTTP request
* @param response the HTTP response
* @param authentication the current authentication (may be null)
*/
void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication);
}Clears SecurityContextHolder and invalidates the session.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.context.SecurityContextRepository;
public class SecurityContextLogoutHandler implements LogoutHandler {
public SecurityContextLogoutHandler();
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
/**
* Returns whether HTTP session is invalidated on logout.
*/
public boolean isInvalidateHttpSession();
/**
* Sets whether to invalidate HTTP session (default: true).
*/
public void setInvalidateHttpSession(boolean invalidateHttpSession);
/**
* Sets whether to clear authentication (default: true).
*/
public void setClearAuthentication(boolean clearAuthentication);
/**
* Sets the SecurityContextHolderStrategy.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy);
/**
* Sets the SecurityContextRepository for context removal.
*/
public void setSecurityContextRepository(SecurityContextRepository securityContextRepository);
}Clears specified cookies on logout.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public class CookieClearingLogoutHandler implements LogoutHandler {
/**
* Creates a handler that clears the specified cookies.
*
* @param cookiesToClear the names of cookies to clear
*/
public CookieClearingLogoutHandler(String... cookiesToClear);
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
}Writes headers on logout using a HeaderWriter.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.header.HeaderWriter;
public class HeaderWriterLogoutHandler implements LogoutHandler {
/**
* Creates a handler that writes headers on logout.
*
* @param headerWriter the HeaderWriter to use
*/
public HeaderWriterLogoutHandler(HeaderWriter headerWriter);
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
}Clears CSRF token on logout.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.csrf.CsrfTokenRepository;
public class CsrfLogoutHandler implements LogoutHandler {
/**
* Creates a handler that clears CSRF tokens using the given repository.
*
* @param csrfTokenRepository the CSRF token repository
*/
public CsrfLogoutHandler(CsrfTokenRepository csrfTokenRepository);
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
}Delegates to multiple logout handlers in sequence.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public class CompositeLogoutHandler implements LogoutHandler {
/**
* Creates a composite handler with multiple delegates.
*
* @param logoutHandlers the logout handlers to invoke
*/
public CompositeLogoutHandler(LogoutHandler... logoutHandlers);
/**
* Invokes all logout handlers in order.
*/
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
}Strategy for handling successful logout.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.core.Authentication;
public interface LogoutSuccessHandler {
/**
* Called when logout succeeds.
*
* @param request the HTTP request
* @param response the HTTP response
* @param authentication the authentication (may be null)
*/
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
}Redirects to a URL on logout success.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.core.Authentication;
public class SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
/**
* Creates a handler with default target URL "/".
*/
public SimpleUrlLogoutSuccessHandler();
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
public void setDefaultTargetUrl(String defaultTargetUrl);
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl);
public void setTargetUrlParameter(String targetUrlParameter);
public void setUseReferer(boolean useReferer);
}Forwards to a URL on logout success.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.core.Authentication;
public class ForwardLogoutSuccessHandler implements LogoutSuccessHandler {
/**
* Creates a handler that forwards to the specified URL.
*
* @param forwardUrl the URL to forward to
*/
public ForwardLogoutSuccessHandler(String forwardUrl);
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
}Returns an HTTP status code on logout success.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
public class HttpStatusReturningLogoutSuccessHandler implements LogoutSuccessHandler {
/**
* Creates a handler returning HTTP 200 OK.
*/
public HttpStatusReturningLogoutSuccessHandler();
/**
* Creates a handler returning the specified HTTP status.
*/
public HttpStatusReturningLogoutSuccessHandler(HttpStatus httpStatusToReturn);
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
}Delegates to logout success handlers based on request matcher.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedHashMap;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.matcher.RequestMatcher;
public class DelegatingLogoutSuccessHandler implements LogoutSuccessHandler {
/**
* Creates a delegating handler.
*
* @param matcherToHandler map of RequestMatcher to LogoutSuccessHandler
*/
public DelegatingLogoutSuccessHandler(
LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler);
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
/**
* Sets the default handler when no matcher matches.
*/
public void setDefaultLogoutSuccessHandler(LogoutSuccessHandler defaultLogoutSuccessHandler);
}Processes logout requests.
package org.springframework.security.web.authentication.logout;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.GenericFilterBean;
public class LogoutFilter extends GenericFilterBean {
/**
* Creates a logout filter.
*
* @param logoutSuccessHandler the success handler
* @param handlers the logout handlers
*/
public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
/**
* Sets the SecurityContextHolderStrategy.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy);
/**
* Sets the request matcher for logout (default: POST /logout).
*/
public void setLogoutRequestMatcher(RequestMatcher logoutRequestMatcher);
/**
* Sets the logout URL (convenience method).
*/
public void setFilterProcessesUrl(String filterProcessesUrl);
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class LogoutConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.logout(logout -> logout
.logoutUrl("/perform-logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID", "remember-me")
.permitAll()
);
return http.build();
}
}import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
private final AuditLogger auditLogger;
public CustomLogoutSuccessHandler(AuditLogger auditLogger) {
this.auditLogger = auditLogger;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
// Log logout event
if (authentication != null) {
String username = authentication.getName();
String ipAddress = request.getRemoteAddr();
auditLogger.logLogout(username, ipAddress);
}
// For AJAX requests, return JSON
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json");
response.getWriter().write("{\"message\": \"Logout successful\"}");
return;
}
// For regular requests, redirect
response.sendRedirect("/login?logout=true");
}
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
@Configuration
public class MultipleLogoutHandlersConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.logout(logout -> logout
.logoutUrl("/logout")
.addLogoutHandler(new SecurityContextLogoutHandler())
.addLogoutHandler(new CookieClearingLogoutHandler("remember-me", "custom-cookie"))
.addLogoutHandler(customLogoutHandler())
.logoutSuccessUrl("/login?logout")
);
return http.build();
}
@Bean
public LogoutHandler customLogoutHandler() {
return (request, response, authentication) -> {
// Custom cleanup logic
if (authentication != null) {
String username = authentication.getName();
// Clear user-specific caches, close connections, etc.
}
};
}
}Install with Tessl CLI
npx tessl i tessl/maven-spring-security-web