diff --git a/web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java b/web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java index 98a2815f7f2..4e692a3f207 100644 --- a/web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java +++ b/web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java @@ -55,6 +55,8 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository { private String cookiePath; + private String cookieDomain; + public CookieCsrfTokenRepository() { this.setHttpOnlyMethod = ReflectionUtils.findMethod(Cookie.class, "setHttpOnly", boolean.class); if (this.setHttpOnlyMethod != null) { @@ -88,6 +90,9 @@ public void saveToken(CsrfToken token, HttpServletRequest request, if (cookieHttpOnly && setHttpOnlyMethod != null) { ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE); } + if (this.cookieDomain != null && !this.cookieDomain.isEmpty()) { + cookie.setDomain(this.cookieDomain); + } response.addCookie(cookie); } @@ -194,4 +199,16 @@ public void setCookiePath(String path) { public String getCookiePath() { return this.cookiePath; } + + /** + * Sets the domain of the cookie that the expected CSRF token is saved to and read from. + * + * @since 5.2 + * @param cookieDomain the domain of the cookie that the expected CSRF token is saved to + * and read from + */ + public void setCookieDomain(String cookieDomain) { + this.cookieDomain = cookieDomain; + } + } diff --git a/web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java b/web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java index b0cdf67bafb..5eeeb9becef 100644 --- a/web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java +++ b/web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java @@ -189,6 +189,20 @@ public void saveTokenNullCustomPath() { assertThat(tokenCookie.getPath()).isEqualTo(this.request.getContextPath()); } + @Test + public void saveTokenWithCookieDomain() { + String domainName = "example.com"; + this.repository.setCookieDomain(domainName); + + 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.getDomain()).isEqualTo(domainName); + } + @Test public void loadTokenNoCookiesNull() { assertThat(this.repository.loadToken(this.request)).isNull();