Skip to content

Commit d4218c7

Browse files
Rob Winchjgrandja
authored andcommitted
Update CookieCsrfTokenRepository docs to cookiHttpOnly=false
Currently CookieCsrfTokenRepository does not specify that the httpOnly flag needs set to false. We should update the reference to include this setting (and a comment about it) since it states that the settings will work with AngularJS. This commit updates the documentation and provides a convenience factory method to create a CookieCsrfTokenRepository with cookiHttpOnly=false Fixes gh-3865
1 parent 64f5362 commit d4218c7

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

docs/manual/src/docs/asciidoc/index.adoc

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3359,9 +3359,19 @@ You can configure `CookieCsrfTokenRepository` in XML using the following:
33593359
<!-- ... -->
33603360
<csrf token-repository-ref="tokenRepository"/>
33613361
</http>
3362-
<b:bean id="tokenRepository" class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"/>
3362+
<b:bean id="tokenRepository"
3363+
class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
3364+
p:cookieHttpOnly="false"/>
33633365
----
33643366

3367+
[NOTE]
3368+
====
3369+
The sample explicitly sets `cookieHttpOnly=false`.
3370+
This is necessary to allow JavaScript (i.e. AngularJS) to read it.
3371+
If you do not need the ability to read the cookie with JavaScript directly, it is recommended to omit `cookieHttpOnly=false` to improve security.
3372+
====
3373+
3374+
33653375
You can configure `CookieCsrfTokenRepository` in Java Configuration using:
33663376

33673377
[source,java]
@@ -3374,11 +3384,18 @@ public class WebSecurityConfig extends
33743384
protected void configure(HttpSecurity http) throws Exception {
33753385
http
33763386
.csrf()
3377-
.csrfTokenRepository(new CookieCsrfTokenRepository());
3387+
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
33783388
}
33793389
}
33803390
----
33813391

3392+
[NOTE]
3393+
====
3394+
The sample explicitly sets `cookieHttpOnly=false`.
3395+
This is necessary to allow JavaScript (i.e. AngularJS) to read it.
3396+
If you do not need the ability to read the cookie with JavaScript directly, it is recommended to omit `cookieHttpOnly=false` (by using `new CookieCsrfTokenRepository()` instead) to improve security.
3397+
====
3398+
33823399

33833400
[[csrf-caveats]]
33843401
=== CSRF Caveats
@@ -6594,9 +6611,9 @@ Spring Security provides `AuthenticationPrincipalArgumentResolver` which can aut
65946611
[source,xml]
65956612
----
65966613
<mvc:annotation-driven>
6597-
<mvc:argument-resolvers>
6598-
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
6599-
</mvc:argument-resolvers>
6614+
<mvc:argument-resolvers>
6615+
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
6616+
</mvc:argument-resolvers>
66006617
</mvc:annotation-driven>
66016618
----
66026619

web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
/**
3232
* A {@link CsrfTokenRepository} that persist the CSRF token in a cookie named
3333
* "XSRF-TOKEN" and reads from the header "X-XSRF-TOKEN" following the conventions of
34-
* AngularJS.
34+
* AngularJS. When using with AngularJS be sure to use {@link #withHttpOnlyFalse()}.
3535
*
3636
* @author Rob Winch
3737
* @since 4.1
@@ -153,6 +153,19 @@ private String getCookiePath(HttpServletRequest request) {
153153
return contextPath.length() > 0 ? contextPath : "/";
154154
}
155155

156+
/**
157+
* Factory method to conveniently create an instance that has
158+
* {@link #setCookieHttpOnly(boolean)} set to false.
159+
*
160+
* @return and instance of CookieCsrfTokenRepository with
161+
* {@link #setCookieHttpOnly(boolean)} set to false
162+
*/
163+
public static CookieCsrfTokenRepository withHttpOnlyFalse() {
164+
CookieCsrfTokenRepository result = new CookieCsrfTokenRepository();
165+
result.setCookieHttpOnly(false);
166+
return result;
167+
}
168+
156169
private String createNewToken() {
157170
return UUID.randomUUID().toString();
158171
}

web/src/test/java/org/springframework/security/web/csrf/CookieCsrfTokenRepositoryTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,18 @@ public void saveTokenHttpOnlyFalse() {
138138
assertThat(tokenCookie.isHttpOnly()).isFalse();
139139
}
140140

141+
@Test
142+
public void saveTokenWithHttpOnlyFalse() {
143+
this.repository = CookieCsrfTokenRepository.withHttpOnlyFalse();
144+
CsrfToken token = this.repository.generateToken(this.request);
145+
this.repository.saveToken(token, this.request, this.response);
146+
147+
Cookie tokenCookie = this.response
148+
.getCookie(CookieCsrfTokenRepository.DEFAULT_CSRF_COOKIE_NAME);
149+
150+
assertThat(tokenCookie.isHttpOnly()).isFalse();
151+
}
152+
141153
@Test
142154
public void loadTokenNoCookiesNull() {
143155
assertThat(this.repository.loadToken(this.request)).isNull();

0 commit comments

Comments
 (0)