Skip to content

Commit 9b43950

Browse files
author
Steve Riesenberg
committed
Merge branch '5.8.x'
2 parents bf1e622 + 8bd25f9 commit 9b43950

File tree

4 files changed

+72
-10
lines changed

4 files changed

+72
-10
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ public void handle(HttpServletRequest request, HttpServletResponse response,
5959
}
6060

6161
private Supplier<CsrfToken> deferCsrfTokenUpdate(Supplier<CsrfToken> csrfTokenSupplier) {
62-
return () -> {
62+
return new CachedCsrfTokenSupplier(() -> {
6363
CsrfToken csrfToken = csrfTokenSupplier.get();
6464
Assert.state(csrfToken != null, "csrfToken supplier returned null");
6565
String updatedToken = createXoredCsrfToken(this.secureRandom, csrfToken.getToken());
6666
return new DefaultCsrfToken(csrfToken.getHeaderName(), csrfToken.getParameterName(), updatedToken);
67-
};
67+
});
6868
}
6969

7070
@Override
@@ -123,4 +123,24 @@ private static byte[] xorCsrf(byte[] randomBytes, byte[] csrfBytes) {
123123
return xoredCsrf;
124124
}
125125

126+
private static final class CachedCsrfTokenSupplier implements Supplier<CsrfToken> {
127+
128+
private final Supplier<CsrfToken> delegate;
129+
130+
private CsrfToken csrfToken;
131+
132+
private CachedCsrfTokenSupplier(Supplier<CsrfToken> delegate) {
133+
this.delegate = delegate;
134+
}
135+
136+
@Override
137+
public CsrfToken get() {
138+
if (this.csrfToken == null) {
139+
this.csrfToken = this.delegate.get();
140+
}
141+
return this.csrfToken;
142+
}
143+
144+
}
145+
126146
}

web/src/main/java/org/springframework/security/web/server/csrf/XorServerCsrfTokenRequestAttributeHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public void handle(ServerWebExchange exchange, Mono<CsrfToken> csrfToken) {
5353
Assert.notNull(exchange, "exchange cannot be null");
5454
Assert.notNull(csrfToken, "csrfToken cannot be null");
5555
Mono<CsrfToken> updatedCsrfToken = csrfToken.map((token) -> new DefaultCsrfToken(token.getHeaderName(),
56-
token.getParameterName(), createXoredCsrfToken(this.secureRandom, token.getToken())));
56+
token.getParameterName(), createXoredCsrfToken(this.secureRandom, token.getToken())))
57+
.cast(CsrfToken.class).cache();
5758
super.handle(exchange, updatedCsrfToken);
5859
}
5960

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,31 @@ public void handleWhenValidParametersThenRequestAttributesSet() {
153153
assertThat(this.request.getAttribute("_csrf")).isNotNull();
154154
}
155155

156+
@Test
157+
public void handleWhenCsrfTokenRequestedTwiceThenCached() {
158+
this.handler.handle(this.request, this.response, () -> this.token);
159+
160+
CsrfToken csrfTokenAttribute = (CsrfToken) this.request.getAttribute(CsrfToken.class.getName());
161+
assertThat(csrfTokenAttribute.getToken()).isNotEqualTo(this.token.getToken());
162+
assertThat(csrfTokenAttribute.getToken()).isEqualTo(csrfTokenAttribute.getToken());
163+
}
164+
156165
@Test
157166
public void resolveCsrfTokenValueWhenRequestIsNullThenThrowsIllegalArgumentException() {
158-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.resolveCsrfTokenValue(null, this.token))
167+
// @formatter:off
168+
assertThatIllegalArgumentException()
169+
.isThrownBy(() -> this.handler.resolveCsrfTokenValue(null, this.token))
159170
.withMessage("request cannot be null");
171+
// @formatter:on
160172
}
161173

162174
@Test
163175
public void resolveCsrfTokenValueWhenCsrfTokenIsNullThenThrowsIllegalArgumentException() {
164-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.resolveCsrfTokenValue(this.request, null))
176+
// @formatter:off
177+
assertThatIllegalArgumentException()
178+
.isThrownBy(() -> this.handler.resolveCsrfTokenValue(this.request, null))
165179
.withMessage("csrfToken cannot be null");
180+
// @formatter:on
166181
}
167182

168183
@Test

web/src/test/java/org/springframework/security/web/server/csrf/XorServerCsrfTokenRequestAttributeHandlerTests.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,29 @@ public void setUp() {
6868

6969
@Test
7070
public void setSecureRandomWhenNullThenThrowsIllegalArgumentException() {
71-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.setSecureRandom(null))
71+
// @formatter:off
72+
assertThatIllegalArgumentException()
73+
.isThrownBy(() -> this.handler.setSecureRandom(null))
7274
.withMessage("secureRandom cannot be null");
75+
// @formatter:on
7376
}
7477

7578
@Test
7679
public void handleWhenExchangeIsNullThenThrowsIllegalArgumentException() {
77-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.handle(null, Mono.just(this.token)))
80+
// @formatter:off
81+
assertThatIllegalArgumentException()
82+
.isThrownBy(() -> this.handler.handle(null, Mono.just(this.token)))
7883
.withMessage("exchange cannot be null");
84+
// @formatter:on
7985
}
8086

8187
@Test
8288
public void handleWhenCsrfTokenIsNullThenThrowsIllegalArgumentException() {
83-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.handle(this.exchange, null))
89+
// @formatter:off
90+
assertThatIllegalArgumentException()
91+
.isThrownBy(() -> this.handler.handle(this.exchange, null))
8492
.withMessage("csrfToken cannot be null");
93+
// @formatter:on
8594
}
8695

8796
@Test
@@ -110,16 +119,33 @@ public void handleWhenValidParametersThenExchangeAttributeSet() {
110119
verify(this.secureRandom).nextBytes(anyByteArray());
111120
}
112121

122+
@Test
123+
public void handleWhenCsrfTokenRequestedTwiceThenCached() {
124+
this.handler.handle(this.exchange, Mono.just(this.token));
125+
Mono<CsrfToken> csrfTokenAttribute = this.exchange.getAttribute(CsrfToken.class.getName());
126+
assertThat(csrfTokenAttribute).isNotNull();
127+
CsrfToken csrfToken1 = csrfTokenAttribute.block();
128+
CsrfToken csrfToken2 = csrfTokenAttribute.block();
129+
assertThat(csrfToken1.getToken()).isNotEqualTo(this.token.getToken());
130+
assertThat(csrfToken1.getToken()).isEqualTo(csrfToken2.getToken());
131+
}
132+
113133
@Test
114134
public void resolveCsrfTokenValueWhenExchangeIsNullThenThrowsIllegalArgumentException() {
115-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.resolveCsrfTokenValue(null, this.token))
135+
// @formatter:off
136+
assertThatIllegalArgumentException()
137+
.isThrownBy(() -> this.handler.resolveCsrfTokenValue(null, this.token))
116138
.withMessage("exchange cannot be null");
139+
// @formatter:on
117140
}
118141

119142
@Test
120143
public void resolveCsrfTokenValueWhenCsrfTokenIsNullThenThrowsIllegalArgumentException() {
121-
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.resolveCsrfTokenValue(this.exchange, null))
144+
// @formatter:off
145+
assertThatIllegalArgumentException()
146+
.isThrownBy(() -> this.handler.resolveCsrfTokenValue(this.exchange, null))
122147
.withMessage("csrfToken cannot be null");
148+
// @formatter:on
123149
}
124150

125151
@Test

0 commit comments

Comments
 (0)