Add cookiePath to CookieCsrfTokenRepository

Allow the csrf cookie path to be set instead of inferred from the
request context.

Fixes gh-4062
This commit is contained in:
Julio Valcarcel 2016-09-16 11:02:09 -04:00 committed by Rob Winch
parent c75a5b7279
commit 6834467389
2 changed files with 67 additions and 3 deletions

View File

@ -53,6 +53,8 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
private boolean cookieHttpOnly;
private String cookiePath;
public CookieCsrfTokenRepository() {
this.setHttpOnlyMethod = ReflectionUtils.findMethod(Cookie.class, "setHttpOnly", boolean.class);
if (this.setHttpOnlyMethod != null) {
@ -72,7 +74,11 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
String tokenValue = token == null ? "" : token.getToken();
Cookie cookie = new Cookie(this.cookieName, tokenValue);
cookie.setSecure(request.isSecure());
cookie.setPath(getCookiePath(request));
if (this.cookiePath != null && !this.cookiePath.isEmpty()) {
cookie.setPath(this.cookiePath);
} else {
cookie.setPath(this.getRequestContext(request));
}
if (token == null) {
cookie.setMaxAge(0);
}
@ -148,7 +154,7 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
this.cookieHttpOnly = cookieHttpOnly;
}
private String getCookiePath(HttpServletRequest request) {
private String getRequestContext(HttpServletRequest request) {
String contextPath = request.getContextPath();
return contextPath.length() > 0 ? contextPath : "/";
}
@ -169,4 +175,23 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
private String createNewToken() {
return UUID.randomUUID().toString();
}
}
/**
* Set the path that the Cookie will be created with. This will will override the default functionality which uses the
* request context as the path.
*
* @param path the path to use
*/
public void setCookiePath(String path) {
this.cookiePath = path;
}
/**
* Get the path that the CSRF cookie will be set to.
*
* @return the path to be used.
*/
public String getCookiePath() {
return this.cookiePath;
}
}

View File

@ -150,6 +150,45 @@ public class CookieCsrfTokenRepositoryTests {
assertThat(tokenCookie.isHttpOnly()).isFalse();
}
@Test
public void saveTokenCustomPath() {
String customPath = "/custompath";
this.repository.setCookiePath(customPath);
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.getPath()).isEqualTo(this.repository.getCookiePath());
}
@Test
public void saveTokenEmptyCustomPath() {
String customPath = "";
this.repository.setCookiePath(customPath);
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.getPath()).isEqualTo(this.request.getContextPath());
}
@Test
public void saveTokenNullCustomPath() {
String customPath = null;
this.repository.setCookiePath(customPath);
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.getPath()).isEqualTo(this.request.getContextPath());
}
@Test
public void loadTokenNoCookiesNull() {
assertThat(this.repository.loadToken(this.request)).isNull();