0
# CSRF Protection
1
2
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.
3
4
## Core CSRF Components
5
6
### CSRF Token
7
8
Represents a CSRF token with its value and metadata.
9
10
```java { .api }
11
public interface CsrfToken extends Serializable {
12
// Get the token value
13
String getToken();
14
15
// Get the HTTP parameter name for the token
16
String getParameterName();
17
18
// Get the HTTP header name for the token
19
String getHeaderName();
20
}
21
22
public final class DefaultCsrfToken implements CsrfToken {
23
// Constructor
24
public DefaultCsrfToken(String headerName, String parameterName, String token);
25
26
// CsrfToken implementation
27
public String getHeaderName();
28
public String getParameterName();
29
public String getToken();
30
}
31
```
32
33
### Deferred CSRF Token
34
35
Provides lazy loading of CSRF tokens to improve performance.
36
37
```java { .api }
38
public interface DeferredCsrfToken {
39
// Get the token (may trigger generation)
40
CsrfToken get();
41
42
// Check if token has been generated
43
boolean isGenerated();
44
}
45
46
public final class RepositoryDeferredCsrfToken implements DeferredCsrfToken {
47
// Constructor
48
public RepositoryDeferredCsrfToken(CsrfTokenRepository delegate, HttpServletRequest request,
49
HttpServletResponse response);
50
51
// DeferredCsrfToken implementation
52
public CsrfToken get();
53
public boolean isGenerated();
54
}
55
```
56
57
## CSRF Token Repository
58
59
Manages the storage and retrieval of CSRF tokens.
60
61
```java { .api }
62
public interface CsrfTokenRepository {
63
// Generate a new token
64
CsrfToken generateToken(HttpServletRequest request);
65
66
// Save a token
67
void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
68
69
// Load an existing token
70
CsrfToken loadToken(HttpServletRequest request);
71
}
72
```
73
74
### HTTP Session Repository
75
76
Stores CSRF tokens in the HTTP session.
77
78
```java { .api }
79
public final class HttpSessionCsrfTokenRepository implements CsrfTokenRepository {
80
// Constructor
81
public HttpSessionCsrfTokenRepository();
82
83
// Configuration
84
public void setSessionAttributeName(String sessionAttributeName);
85
public void setParameterName(String parameterName);
86
public void setHeaderName(String headerName);
87
88
// CsrfTokenRepository implementation
89
public CsrfToken generateToken(HttpServletRequest request);
90
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
91
public CsrfToken loadToken(HttpServletRequest request);
92
}
93
```
94
95
### Cookie Repository
96
97
Stores CSRF tokens in HTTP cookies.
98
99
```java { .api }
100
public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
101
// Static factory methods
102
public static CookieCsrfTokenRepository withHttpOnlyFalse();
103
104
// Configuration methods
105
public void setCookieName(String cookieName);
106
public void setCookiePath(String path);
107
public void setCookieDomain(String cookieDomain);
108
public void setCookieMaxAge(int cookieMaxAge);
109
public void setCookieHttpOnly(boolean cookieHttpOnly);
110
public void setSecure(Boolean secure);
111
public void setSameSite(String sameSite);
112
public void setParameterName(String parameterName);
113
public void setHeaderName(String headerName);
114
115
// CsrfTokenRepository implementation
116
public CsrfToken generateToken(HttpServletRequest request);
117
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response);
118
public CsrfToken loadToken(HttpServletRequest request);
119
}
120
```
121
122
### Usage Examples
123
124
```java
125
// HTTP Session storage (default)
126
CsrfTokenRepository sessionRepository = new HttpSessionCsrfTokenRepository();
127
128
// Cookie storage with HTTP-only disabled for JavaScript access
129
CsrfTokenRepository cookieRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
130
131
// Custom cookie configuration
132
CookieCsrfTokenRepository customCookieRepository = new CookieCsrfTokenRepository();
133
customCookieRepository.setCookieName("XSRF-TOKEN");
134
customCookieRepository.setCookiePath("/");
135
customCookieRepository.setSecure(true);
136
customCookieRepository.setSameSite("Strict");
137
138
// Lazy token repository to defer generation
139
LazyCsrfTokenRepository lazyRepository = new LazyCsrfTokenRepository(sessionRepository);
140
```
141
142
## CSRF Filter
143
144
The main filter that enforces CSRF protection.
145
146
```java { .api }
147
public final class CsrfFilter extends OncePerRequestFilter {
148
// Constructor
149
public CsrfFilter(CsrfTokenRepository csrfTokenRepository);
150
151
// Configuration methods
152
public void setRequireCsrfProtectionMatcher(RequestMatcher requireCsrfProtectionMatcher);
153
public void setAccessDeniedHandler(AccessDeniedHandler accessDeniedHandler);
154
public void setCsrfTokenRequestHandler(CsrfTokenRequestHandler csrfTokenRequestHandler);
155
public void setCsrfTokenRequestResolver(CsrfTokenRequestResolver csrfTokenRequestResolver);
156
157
// Filter implementation
158
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
159
FilterChain filterChain) throws ServletException, IOException;
160
}
161
```
162
163
### Usage Example
164
165
```java
166
// Basic CSRF filter setup
167
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
168
169
// Skip CSRF for specific paths
170
csrfFilter.setRequireCsrfProtectionMatcher(
171
new NegatedRequestMatcher(
172
new OrRequestMatcher(
173
new AntPathRequestMatcher("/api/public/**"),
174
new AntPathRequestMatcher("/webhook/**")
175
)
176
)
177
);
178
179
// Custom access denied handler
180
csrfFilter.setAccessDeniedHandler(new HttpStatusAccessDeniedHandler(HttpStatus.FORBIDDEN));
181
```
182
183
## CSRF Token Request Handling
184
185
### Token Request Handler
186
187
Handles CSRF token processing for requests.
188
189
```java { .api }
190
public interface CsrfTokenRequestHandler {
191
// Handle token for request
192
void handle(HttpServletRequest request, HttpServletResponse response,
193
Supplier<CsrfToken> csrfToken);
194
195
// Resolve token value from request
196
String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
197
}
198
199
public final class CsrfTokenRequestAttributeHandler implements CsrfTokenRequestHandler {
200
// CsrfTokenRequestHandler implementation
201
public void handle(HttpServletRequest request, HttpServletResponse response,
202
Supplier<CsrfToken> csrfToken);
203
public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
204
}
205
206
public final class XorCsrfTokenRequestAttributeHandler implements CsrfTokenRequestHandler {
207
// CsrfTokenRequestHandler implementation
208
public void handle(HttpServletRequest request, HttpServletResponse response,
209
Supplier<CsrfToken> csrfToken);
210
public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
211
}
212
```
213
214
### Token Request Resolver
215
216
Resolves CSRF token values from HTTP requests.
217
218
```java { .api }
219
public interface CsrfTokenRequestResolver {
220
// Resolve token value from request
221
String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
222
}
223
```
224
225
## CSRF Exceptions
226
227
CSRF-related exceptions that can be thrown during processing.
228
229
```java { .api }
230
public class CsrfException extends RuntimeException {
231
// Constructors
232
public CsrfException(String message);
233
public CsrfException(String message, Throwable cause);
234
}
235
236
public class InvalidCsrfTokenException extends CsrfException {
237
// Constructors
238
public InvalidCsrfTokenException(String message);
239
public InvalidCsrfTokenException(String message, Throwable cause);
240
}
241
242
public class MissingCsrfTokenException extends CsrfException {
243
// Constructors
244
public MissingCsrfTokenException(String message);
245
public MissingCsrfTokenException(String message, Throwable cause);
246
}
247
```
248
249
## CSRF Integration Components
250
251
### CSRF Authentication Strategy
252
253
Integrates CSRF protection with authentication.
254
255
```java { .api }
256
public final class CsrfAuthenticationStrategy implements SessionAuthenticationStrategy {
257
// Constructor
258
public CsrfAuthenticationStrategy(CsrfTokenRepository csrfTokenRepository);
259
260
// SessionAuthenticationStrategy implementation
261
public void onAuthentication(Authentication authentication, HttpServletRequest request,
262
HttpServletResponse response) throws SessionAuthenticationException;
263
}
264
```
265
266
### CSRF Logout Handler
267
268
Handles CSRF token cleanup on logout.
269
270
```java { .api }
271
public final class CsrfLogoutHandler implements LogoutHandler {
272
// Constructor
273
public CsrfLogoutHandler(CsrfTokenRepository csrfTokenRepository);
274
275
// LogoutHandler implementation
276
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication);
277
}
278
```
279
280
## Common CSRF Protection Patterns
281
282
### Basic Web Application
283
284
```java
285
// Standard session-based CSRF protection
286
CsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
287
CsrfFilter csrfFilter = new CsrfFilter(repository);
288
289
// Configure logout to clear CSRF token
290
CsrfLogoutHandler logoutHandler = new CsrfLogoutHandler(repository);
291
292
// Configure authentication to regenerate CSRF token
293
CsrfAuthenticationStrategy authStrategy = new CsrfAuthenticationStrategy(repository);
294
```
295
296
### Single Page Application (SPA)
297
298
```java
299
// Cookie-based CSRF for JavaScript access
300
CookieCsrfTokenRepository cookieRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
301
CsrfFilter csrfFilter = new CsrfFilter(cookieRepository);
302
303
// Use XOR encoding for additional security
304
csrfFilter.setCsrfTokenRequestHandler(new XorCsrfTokenRequestAttributeHandler());
305
```
306
307
### API with Selective CSRF
308
309
```java
310
// Skip CSRF for public API endpoints
311
RequestMatcher csrfMatcher = new NegatedRequestMatcher(
312
new OrRequestMatcher(
313
new AntPathRequestMatcher("/api/public/**"),
314
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")
315
)
316
);
317
318
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
319
csrfFilter.setRequireCsrfProtectionMatcher(csrfMatcher);
320
```
321
322
### Stateless Application
323
324
```java
325
// Disable CSRF for stateless applications
326
RequestMatcher skipCsrf = new NegatedRequestMatcher(AnyRequestMatcher.INSTANCE);
327
CsrfFilter csrfFilter = new CsrfFilter(new HttpSessionCsrfTokenRepository());
328
csrfFilter.setRequireCsrfProtectionMatcher(skipCsrf);
329
```
330
331
## Frontend Integration
332
333
### HTML Forms
334
335
```html
336
<!-- Include CSRF token in forms -->
337
<form method="post" action="/submit">
338
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
339
<input type="text" name="data"/>
340
<button type="submit">Submit</button>
341
</form>
342
```
343
344
### JavaScript/AJAX
345
346
```javascript
347
// Get CSRF token from cookie (if using CookieCsrfTokenRepository)
348
function getCsrfToken() {
349
return document.cookie
350
.split('; ')
351
.find(row => row.startsWith('XSRF-TOKEN='))
352
?.split('=')[1];
353
}
354
355
// Include in AJAX requests
356
fetch('/api/data', {
357
method: 'POST',
358
headers: {
359
'X-XSRF-TOKEN': getCsrfToken(),
360
'Content-Type': 'application/json'
361
},
362
body: JSON.stringify(data)
363
});
364
```
365
366
## Error Handling
367
368
CSRF protection can fail for several reasons:
369
- **MissingCsrfTokenException**: No CSRF token provided in request
370
- **InvalidCsrfTokenException**: CSRF token doesn't match expected value
371
- **CsrfException**: General CSRF processing error
372
373
These exceptions are typically handled by the configured `AccessDeniedHandler`, which can return appropriate error responses or redirect to error pages.