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.
}
};
}
}