Skip to content

Commit 2a6e00c

Browse files
committed
Don't Cache ReactiveJwtDecoders Errors
Closes gh-10444
1 parent 09a14bf commit 2a6e00c

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.security.oauth2.server.resource.authentication;
1818

19+
import java.time.Duration;
1920
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.Collection;
@@ -186,7 +187,7 @@ public Mono<ReactiveAuthenticationManager> resolve(String issuer) {
186187
return this.authenticationManagers.computeIfAbsent(issuer,
187188
(k) -> Mono.<ReactiveAuthenticationManager>fromCallable(() -> new JwtReactiveAuthenticationManager(ReactiveJwtDecoders.fromIssuerLocation(k)))
188189
.subscribeOn(Schedulers.boundedElastic())
189-
.cache()
190+
.cache((manager) -> Duration.ofMillis(Long.MAX_VALUE), (ex) -> Duration.ZERO, () -> Duration.ZERO)
190191
);
191192
// @formatter:on
192193
}

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java

+34
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,40 @@ public void resolveWhenUsingTrustedIssuerThenReturnsAuthenticationManager() thro
9696
}
9797
}
9898

99+
@Test
100+
public void resolveWhednUsingTrustedIssuerThenReturnsAuthenticationManager() throws Exception {
101+
try (MockWebServer server = new MockWebServer()) {
102+
server.start();
103+
String issuer = server.url("").toString();
104+
// @formatter:off
105+
server.enqueue(new MockResponse().setResponseCode(500)
106+
.setHeader("Content-Type", "application/json")
107+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer))
108+
);
109+
server.enqueue(new MockResponse().setResponseCode(200)
110+
.setHeader("Content-Type", "application/json")
111+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer))
112+
);
113+
server.enqueue(new MockResponse().setResponseCode(200)
114+
.setHeader("Content-Type", "application/json")
115+
.setBody(JWK_SET)
116+
);
117+
// @formatter:on
118+
JWSObject jws = new JWSObject(new JWSHeader(JWSAlgorithm.RS256),
119+
new Payload(new JSONObject(Collections.singletonMap(JwtClaimNames.ISS, issuer))));
120+
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
121+
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
122+
issuer);
123+
Authentication token = withBearerToken(jws.serialize());
124+
AuthenticationManager authenticationManager = authenticationManagerResolver.resolve(null);
125+
assertThat(authenticationManager).isNotNull();
126+
assertThatExceptionOfType(IllegalArgumentException.class)
127+
.isThrownBy(() -> authenticationManager.authenticate(token));
128+
Authentication authentication = authenticationManager.authenticate(token);
129+
assertThat(authentication.isAuthenticated()).isTrue();
130+
}
131+
}
132+
99133
@Test
100134
public void resolveWhenUsingSameIssuerThenReturnsSameAuthenticationManager() throws Exception {
101135
try (MockWebServer server = new MockWebServer()) {

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolverTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,34 @@ public void resolveWhenUsingTrustedIssuerThenReturnsAuthenticationManager() thro
9595
}
9696
}
9797

98+
// gh-10444
99+
@Test
100+
public void resolveWhednUsingTrustedIssuerThenReturnsAuthenticationManager() throws Exception {
101+
try (MockWebServer server = new MockWebServer()) {
102+
String issuer = server.url("").toString();
103+
// @formatter:off
104+
server.enqueue(new MockResponse().setResponseCode(500).setHeader("Content-Type", "application/json")
105+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer)));
106+
server.enqueue(new MockResponse().setResponseCode(200).setHeader("Content-Type", "application/json")
107+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer)));
108+
server.enqueue(new MockResponse().setResponseCode(200).setHeader("Content-Type", "application/json")
109+
.setBody(JWK_SET));
110+
// @formatter:on
111+
JWSObject jws = new JWSObject(new JWSHeader(JWSAlgorithm.RS256),
112+
new Payload(new JSONObject(Collections.singletonMap(JwtClaimNames.ISS, issuer))));
113+
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
114+
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerReactiveAuthenticationManagerResolver(
115+
issuer);
116+
ReactiveAuthenticationManager authenticationManager = authenticationManagerResolver.resolve(null).block();
117+
assertThat(authenticationManager).isNotNull();
118+
Authentication token = withBearerToken(jws.serialize());
119+
assertThatExceptionOfType(IllegalArgumentException.class)
120+
.isThrownBy(() -> authenticationManager.authenticate(token).block());
121+
Authentication authentication = authenticationManager.authenticate(token).block();
122+
assertThat(authentication.isAuthenticated()).isTrue();
123+
}
124+
}
125+
98126
@Test
99127
public void resolveWhenUsingSameIssuerThenReturnsSameAuthenticationManager() throws Exception {
100128
try (MockWebServer server = new MockWebServer()) {

0 commit comments

Comments
 (0)