2
0
Эх сурвалжийг харах

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 жил өмнө
parent
commit
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));
+	}
+
 }