15
15
*/
16
16
17
17
package org .springframework .security .web .csrf ;
18
-
19
18
import java .util .UUID ;
19
+ import java .util .function .Consumer ;
20
20
21
- import jakarta .servlet .ServletRequest ;
22
21
import jakarta .servlet .http .Cookie ;
23
22
import jakarta .servlet .http .HttpServletRequest ;
24
23
import jakarta .servlet .http .HttpServletResponse ;
25
24
25
+ import org .springframework .http .HttpHeaders ;
26
+ import org .springframework .http .ResponseCookie ;
26
27
import org .springframework .util .Assert ;
27
28
import org .springframework .util .StringUtils ;
28
29
import org .springframework .web .util .WebUtils ;
34
35
*
35
36
* @author Rob Winch
36
37
* @author Steve Riesenberg
38
+ * @author Alex Montoya
37
39
* @since 4.1
38
40
*/
39
41
public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
@@ -63,7 +65,17 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
63
65
64
66
private int cookieMaxAge = -1 ;
65
67
66
- public CookieCsrfTokenRepository () {
68
+ private Consumer <ResponseCookie .ResponseCookieBuilder > cookieCustomizer = (builder ) -> {};
69
+
70
+ /**
71
+ * Add a {@link Consumer} for a {@code ResponseCookieBuilder} that will be invoked
72
+ * for each cookie being built, just before the call to {@code build()}.
73
+ * @param cookieCustomizer consumer for a cookie builder
74
+ * @since 6.1
75
+ */
76
+ public void setCookieCustomizer (Consumer <ResponseCookie .ResponseCookieBuilder > cookieCustomizer ) {
77
+ Assert .notNull (cookieCustomizer , "cookieCustomizer must not be null" );
78
+ this .cookieCustomizer = cookieCustomizer ;
67
79
}
68
80
69
81
@ Override
@@ -74,15 +86,17 @@ public CsrfToken generateToken(HttpServletRequest request) {
74
86
@ Override
75
87
public void saveToken (CsrfToken token , HttpServletRequest request , HttpServletResponse response ) {
76
88
String tokenValue = (token != null ) ? token .getToken () : "" ;
77
- Cookie cookie = new Cookie (this .cookieName , tokenValue );
78
- cookie .setSecure ((this .secure != null ) ? this .secure : request .isSecure ());
79
- cookie .setPath (StringUtils .hasLength (this .cookiePath ) ? this .cookiePath : this .getRequestContext (request ));
80
- cookie .setMaxAge ((token != null ) ? this .cookieMaxAge : 0 );
81
- cookie .setHttpOnly (this .cookieHttpOnly );
82
- if (StringUtils .hasLength (this .cookieDomain )) {
83
- cookie .setDomain (this .cookieDomain );
84
- }
85
- response .addCookie (cookie );
89
+
90
+ ResponseCookie .ResponseCookieBuilder cookieBuilder = ResponseCookie .from (this .cookieName , tokenValue )
91
+ .secure (this .secure != null ? this .secure : request .isSecure ())
92
+ .path (StringUtils .hasLength (this .cookiePath ) ? this .cookiePath : this .getRequestContext (request ))
93
+ .maxAge (token != null ? this .cookieMaxAge : 0 )
94
+ .httpOnly (this .cookieHttpOnly )
95
+ .domain (this .cookieDomain );
96
+
97
+ this .cookieCustomizer .accept (cookieBuilder );
98
+
99
+ response .setHeader (HttpHeaders .SET_COOKIE , cookieBuilder .build ().toString ());
86
100
87
101
// Set request attribute to signal that response has blank cookie value,
88
102
// which allows loadToken to return null when token has been removed
@@ -143,11 +157,9 @@ public void setCookieName(String cookieName) {
143
157
}
144
158
145
159
/**
146
- * Sets the HttpOnly attribute on the cookie containing the CSRF token. Defaults to
147
- * <code>true</code>.
148
- * @param cookieHttpOnly <code>true</code> sets the HttpOnly attribute,
149
- * <code>false</code> does not set it
160
+ * @deprecated Use {@link #setCookieCustomizer(Consumer)} instead.
150
161
*/
162
+ @ Deprecated (since = "6.1" )
151
163
public void setCookieHttpOnly (boolean cookieHttpOnly ) {
152
164
this .cookieHttpOnly = cookieHttpOnly ;
153
165
}
@@ -191,51 +203,30 @@ public String getCookiePath() {
191
203
}
192
204
193
205
/**
194
- * Sets the domain of the cookie that the expected CSRF token is saved to and read
195
- * from.
196
- * @param cookieDomain the domain of the cookie that the expected CSRF token is saved
197
- * to and read from
206
+ * @deprecated Use {@link #setCookieCustomizer(Consumer)} instead.
198
207
* @since 5.2
199
208
*/
209
+ @ Deprecated (since = "6.1" )
200
210
public void setCookieDomain (String cookieDomain ) {
201
211
this .cookieDomain = cookieDomain ;
202
212
}
203
213
204
214
/**
205
- * Sets secure flag of the cookie that the expected CSRF token is saved to and read
206
- * from. By default secure flag depends on {@link ServletRequest#isSecure()}
207
- * @param secure the secure flag of the cookie that the expected CSRF token is saved
208
- * to and read from
215
+ * @deprecated Use {@link #setCookieCustomizer(Consumer)} instead.
209
216
* @since 5.4
210
217
*/
218
+ @ Deprecated (since = "6.1" )
211
219
public void setSecure (Boolean secure ) {
212
220
this .secure = secure ;
213
221
}
214
222
215
223
/**
216
- * Sets maximum age in seconds for the cookie that the expected CSRF token is saved to
217
- * and read from. By default maximum age value is -1.
218
- *
219
- * <p>
220
- * A positive value indicates that the cookie will expire after that many seconds have
221
- * passed. Note that the value is the <i>maximum</i> age when the cookie will expire,
222
- * not the cookie's current age.
223
- *
224
- * <p>
225
- * A negative value means that the cookie is not stored persistently and will be
226
- * deleted when the Web browser exits.
227
- *
228
- * <p>
229
- * A zero value causes the cookie to be deleted immediately therefore it is not a
230
- * valid value and in that case an {@link IllegalArgumentException} will be thrown.
231
- * @param cookieMaxAge an integer specifying the maximum age of the cookie in seconds;
232
- * if negative, means the cookie is not stored; if zero, the method throws an
233
- * {@link IllegalArgumentException}
224
+ * @deprecated Use {@link #setCookieCustomizer(Consumer)} instead.
234
225
* @since 5.5
235
226
*/
227
+ @ Deprecated (since = "6.1" )
236
228
public void setCookieMaxAge (int cookieMaxAge ) {
237
229
Assert .isTrue (cookieMaxAge != 0 , "cookieMaxAge cannot be zero" );
238
230
this .cookieMaxAge = cookieMaxAge ;
239
231
}
240
-
241
232
}
0 commit comments