瀏覽代碼

Allow maximum age of csrf cookie to be configured

Allows maxAge of the generated cookie by CookieCsrfTokenRepository
to be configurable.

Prior to this commit, maximum age was set with a value of -1.

After this commit, it will be configured by the user with an either
positive or negative value. If the user does not provide a value,
it will be set -1.

An IllegalArgumentException will be thrown when
this value is set to zero.

Closes gh-9195
Serdar Kuzucu 4 年之前
父節點
當前提交
76e117a67a

+ 29 - 1
web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java

@@ -57,6 +57,8 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
 
 	private Boolean secure;
 
+	private int cookieMaxAge = -1;
+
 	public CookieCsrfTokenRepository() {
 	}
 
@@ -71,7 +73,7 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
 		Cookie cookie = new Cookie(this.cookieName, tokenValue);
 		cookie.setSecure((this.secure != null) ? this.secure : request.isSecure());
 		cookie.setPath(StringUtils.hasLength(this.cookiePath) ? this.cookiePath : this.getRequestContext(request));
-		cookie.setMaxAge((token != null) ? -1 : 0);
+		cookie.setMaxAge((token != null) ? this.cookieMaxAge : 0);
 		cookie.setHttpOnly(this.cookieHttpOnly);
 		if (StringUtils.hasLength(this.cookieDomain)) {
 			cookie.setDomain(this.cookieDomain);
@@ -192,4 +194,30 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
 		this.secure = secure;
 	}
 
+	/**
+	 * Sets maximum age in seconds for the cookie that the expected CSRF token is saved to
+	 * and read from. By default maximum age value is -1.
+	 *
+	 * <p>
+	 * A positive value indicates that the cookie will expire after that many seconds have
+	 * passed. Note that the value is the <i>maximum</i> age when the cookie will expire,
+	 * not the cookie's current age.
+	 *
+	 * <p>
+	 * A negative value means that the cookie is not stored persistently and will be
+	 * deleted when the Web browser exits.
+	 *
+	 * <p>
+	 * A zero value causes the cookie to be deleted immediately therefore it is not a
+	 * valid value and in that case an {@link IllegalArgumentException} will be thrown.
+	 * @param cookieMaxAge an integer specifying the maximum age of the cookie in seconds;
+	 * if negative, means the cookie is not stored; if zero, the method throws an
+	 * {@link IllegalArgumentException}
+	 * @since 5.5
+	 */
+	public void setCookieMaxAge(int cookieMaxAge) {
+		Assert.isTrue(cookieMaxAge != 0, "cookieMaxAge is not zero");
+		this.cookieMaxAge = cookieMaxAge;
+	}
+
 }

+ 15 - 0
web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java

@@ -190,6 +190,16 @@ public class CookieCsrfTokenRepositoryTests {
 		assertThat(tokenCookie.getDomain()).isEqualTo(domainName);
 	}
 
+	@Test
+	public void saveTokenWithCookieMaxAge() {
+		int maxAge = 1200;
+		this.repository.setCookieMaxAge(maxAge);
+		CsrfToken token = this.repository.generateToken(this.request);
+		this.repository.saveToken(token, this.request, this.response);
+		Cookie tokenCookie = this.response.getCookie(CookieCsrfTokenRepository.DEFAULT_CSRF_COOKIE_NAME);
+		assertThat(tokenCookie.getMaxAge()).isEqualTo(maxAge);
+	}
+
 	@Test
 	public void loadTokenNoCookiesNull() {
 		assertThat(this.repository.loadToken(this.request)).isNull();
@@ -251,4 +261,9 @@ public class CookieCsrfTokenRepositoryTests {
 		assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setHeaderName(null));
 	}
 
+	@Test
+	public void setCookieMaxAgeZeroIllegalArgumentException() {
+		assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setCookieMaxAge(0));
+	}
+
 }