Spring Security Web module provides comprehensive web security features for Spring-based applications, including servlet-based authentication, authorization, CSRF protection, session management, and security filter chain implementation
—
Spring Security Web provides comprehensive Cross-Site Request Forgery (CSRF) protection through token-based validation with multiple storage strategies. The CSRF protection system generates, stores, and validates tokens to ensure requests originate from legitimate sources.
Represents a CSRF token with its value and metadata.
public interface CsrfToken extends Serializable {
// Get the token value
String getToken();
// Get the HTTP parameter name for the token
String getParameterName();
// Get the HTTP header name for the token
String getHeaderName();
}
public final class DefaultCsrfToken implements CsrfToken {
// Constructor
public DefaultCsrfToken(String headerName, String parameterName, String token);
// CsrfToken implementation
public String getHeaderName();
public String getParameterName();
public String getToken();
}Provides lazy loading of CSRF tokens to improve performance.
public interface DeferredCsrfToken {
// Get the token (may trigger generation)
CsrfToken get();
// Check if token has been generated
boolean isGenerated();
}
public final class RepositoryDeferredCsrfToken implements DeferredCsrfToken {
// Constructor
public RepositoryDeferredCsrfToken(CsrfTokenRepository delegate, HttpServletRequest request,
HttpServletResponse response);
// DeferredCsrfToken implementation
public CsrfToken get();
public boolean isGenerated();
}Manages the storage and retrieval of CSRF tokens.
public interface CsrfTokenRepository {
// Generate a new token
CsrfToken generateToken(HttpServletRequest request);
// Save a token
void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
// Load an existing token
CsrfToken loadToken(HttpServletRequest request);
}Stores CSRF tokens in the HTTP session.
public final class HttpSessionCsrfTokenRepository implements CsrfTokenRepository {
// Constructor
public HttpSessionCsrfTokenRepository();
// Configuration
public void setSessionAttributeName(String sessionAttributeName);
public void setParameterName(String parameterName);
public void setHeaderName(String headerName);
// CsrfTokenRepository implementation
public CsrfToken generateToken(HttpServletRequest request);
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
public CsrfToken loadToken(HttpServletRequest request);
}Stores CSRF tokens in HTTP cookies.
public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
// Static factory methods
public static CookieCsrfTokenRepository withHttpOnlyFalse();
// Configuration methods
public void setCookieName(String cookieName);
public void setCookiePath(String path);
public void setCookieDomain(String cookieDomain);
public void setCookieMaxAge(int cookieMaxAge);
public void setCookieHttpOnly(boolean cookieHttpOnly);
public void setSecure(Boolean secure);
public void setSameSite(String sameSite);
public void setParameterName(String parameterName);
public void setHeaderName(String headerName);
// CsrfTokenRepository implementation
public CsrfToken generateToken(HttpServletRequest request);
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
public CsrfToken loadToken(HttpServletRequest request);
}// HTTP Session storage (default)
CsrfTokenRepository sessionRepository = new HttpSessionCsrfTokenRepository();
// Cookie storage with HTTP-only disabled for JavaScript access
CsrfTokenRepository cookieRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
// Custom cookie configuration
CookieCsrfTokenRepository customCookieRepository = new CookieCsrfTokenRepository();
customCookieRepository.setCookieName("XSRF-TOKEN");
customCookieRepository.setCookiePath("/");
customCookieRepository.setSecure(true);
customCookieRepository.setSameSite("Strict");
// Lazy token repository to defer generation
LazyCsrfTokenRepository lazyRepository = new LazyCsrfTokenRepository(sessionRepository);The main filter that enforces CSRF protection.
public final class CsrfFilter extends OncePerRequestFilter {
// Constructor
public CsrfFilter(CsrfTokenRepository csrfTokenRepository);
// Configuration methods
public void setRequireCsrfProtectionMatcher(RequestMatcher requireCsrfProtectionMatcher);
public void setAccessDeniedHandler(AccessDeniedHandler accessDeniedHandler);
public void setCsrfTokenRequestHandler(CsrfTokenRequestHandler csrfTokenRequestHandler);
public void setCsrfTokenRequestResolver(CsrfTokenRequestResolver csrfTokenRequestResolver);
// Filter implementation
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException;
}// Basic CSRF filter setup
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
// Skip CSRF for specific paths
csrfFilter.setRequireCsrfProtectionMatcher(
new NegatedRequestMatcher(
new OrRequestMatcher(
new AntPathRequestMatcher("/api/public/**"),
new AntPathRequestMatcher("/webhook/**")
)
)
);
// Custom access denied handler
csrfFilter.setAccessDeniedHandler(new HttpStatusAccessDeniedHandler(HttpStatus.FORBIDDEN));Handles CSRF token processing for requests.
public interface CsrfTokenRequestHandler {
// Handle token for request
void handle(HttpServletRequest request, HttpServletResponse response,
Supplier<CsrfToken> csrfToken);
// Resolve token value from request
String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
}
public final class CsrfTokenRequestAttributeHandler implements CsrfTokenRequestHandler {
// CsrfTokenRequestHandler implementation
public void handle(HttpServletRequest request, HttpServletResponse response,
Supplier<CsrfToken> csrfToken);
public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
}
public final class XorCsrfTokenRequestAttributeHandler implements CsrfTokenRequestHandler {
// CsrfTokenRequestHandler implementation
public void handle(HttpServletRequest request, HttpServletResponse response,
Supplier<CsrfToken> csrfToken);
public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
}Resolves CSRF token values from HTTP requests.
public interface CsrfTokenRequestResolver {
// Resolve token value from request
String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
}CSRF-related exceptions that can be thrown during processing.
public class CsrfException extends RuntimeException {
// Constructors
public CsrfException(String message);
public CsrfException(String message, Throwable cause);
}
public class InvalidCsrfTokenException extends CsrfException {
// Constructors
public InvalidCsrfTokenException(String message);
public InvalidCsrfTokenException(String message, Throwable cause);
}
public class MissingCsrfTokenException extends CsrfException {
// Constructors
public MissingCsrfTokenException(String message);
public MissingCsrfTokenException(String message, Throwable cause);
}Integrates CSRF protection with authentication.
public final class CsrfAuthenticationStrategy implements SessionAuthenticationStrategy {
// Constructor
public CsrfAuthenticationStrategy(CsrfTokenRepository csrfTokenRepository);
// SessionAuthenticationStrategy implementation
public void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response) throws SessionAuthenticationException;
}Handles CSRF token cleanup on logout.
public final class CsrfLogoutHandler implements LogoutHandler {
// Constructor
public CsrfLogoutHandler(CsrfTokenRepository csrfTokenRepository);
// LogoutHandler implementation
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication);
}// Standard session-based CSRF protection
CsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
CsrfFilter csrfFilter = new CsrfFilter(repository);
// Configure logout to clear CSRF token
CsrfLogoutHandler logoutHandler = new CsrfLogoutHandler(repository);
// Configure authentication to regenerate CSRF token
CsrfAuthenticationStrategy authStrategy = new CsrfAuthenticationStrategy(repository);// Cookie-based CSRF for JavaScript access
CookieCsrfTokenRepository cookieRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
CsrfFilter csrfFilter = new CsrfFilter(cookieRepository);
// Use XOR encoding for additional security
csrfFilter.setCsrfTokenRequestHandler(new XorCsrfTokenRequestAttributeHandler());// Skip CSRF for public API endpoints
RequestMatcher csrfMatcher = new NegatedRequestMatcher(
new OrRequestMatcher(
new AntPathRequestMatcher("/api/public/**"),
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")
)
);
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
csrfFilter.setRequireCsrfProtectionMatcher(csrfMatcher);// Disable CSRF for stateless applications
RequestMatcher skipCsrf = new NegatedRequestMatcher(AnyRequestMatcher.INSTANCE);
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
csrfFilter.setRequireCsrfProtectionMatcher(skipCsrf);<!-- Include CSRF token in forms -->
<form method="post" action="/submit">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="text" name="data"/>
<button type="submit">Submit</button>
</form>// Get CSRF token from cookie (if using CookieCsrfTokenRepository)
function getCsrfToken() {
return document.cookie
.split('; ')
.find(row => row.startsWith('XSRF-TOKEN='))
?.split('=')[1];
}
// Include in AJAX requests
fetch('/api/data', {
method: 'POST',
headers: {
'X-XSRF-TOKEN': getCsrfToken(),
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});CSRF protection can fail for several reasons:
These exceptions are typically handled by the configured AccessDeniedHandler, which can return appropriate error responses or redirect to error pages.
Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-security--spring-security-web