Skip to content

Commit 7b03fb5

Browse files
committed
Don't Cache ReactiveJwtDecoders Errors
Closes gh-10444
1 parent 823c1eb commit 7b03fb5

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
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;
@@ -170,7 +171,7 @@ public Mono<ReactiveAuthenticationManager> resolve(String issuer) {
170171
new JwtReactiveAuthenticationManager(ReactiveJwtDecoders.fromIssuerLocation(k))
171172
)
172173
.subscribeOn(Schedulers.boundedElastic())
173-
.cache());
174+
.cache((manager) -> Duration.ofMillis(Long.MAX_VALUE), (ex) -> Duration.ZERO, () -> Duration.ZERO));
174175
}
175176
}
176177
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@
3838
import org.springframework.security.authentication.AuthenticationManagerResolver;
3939
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4040
import org.springframework.security.oauth2.jose.TestKeys;
41+
import org.springframework.security.oauth2.jwt.JwtClaimNames;
4142

4243
import static org.assertj.core.api.Assertions.assertThat;
4344
import static org.assertj.core.api.Assertions.assertThatCode;
45+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4446
import static org.mockito.Mockito.mock;
4547
import static org.springframework.security.oauth2.jwt.JwtClaimNames.ISS;
4648

@@ -85,6 +87,35 @@ public void resolveWhenUsingTrustedIssuerThenReturnsAuthenticationManager() thro
8587
}
8688
}
8789

90+
@Test
91+
public void resolveWhenIssuerFailsThenErrorNotCached() throws Exception {
92+
try (MockWebServer server = new MockWebServer()) {
93+
server.start();
94+
String issuer = server.url("").toString();
95+
// @formatter:off
96+
server.enqueue(new MockResponse().setResponseCode(500)
97+
.setHeader("Content-Type", "application/json")
98+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer))
99+
);
100+
server.enqueue(new MockResponse().setResponseCode(200)
101+
.setHeader("Content-Type", "application/json")
102+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer))
103+
);
104+
// @formatter:on
105+
JWSObject jws = new JWSObject(new JWSHeader(JWSAlgorithm.RS256),
106+
new Payload(new JSONObject(Collections.singletonMap(JwtClaimNames.ISS, issuer))));
107+
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
108+
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
109+
issuer);
110+
MockHttpServletRequest request = new MockHttpServletRequest();
111+
request.addHeader("Authorization", "Bearer " + jws.serialize());
112+
assertThatExceptionOfType(IllegalArgumentException.class)
113+
.isThrownBy(() -> authenticationManagerResolver.resolve(request));
114+
AuthenticationManager authenticationManager = authenticationManagerResolver.resolve(request);
115+
assertThat(authenticationManager).isNotNull();
116+
}
117+
}
118+
88119
@Test
89120
public void resolveWhenUsingUntrustedIssuerThenException() {
90121
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver =

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040
import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver;
4141
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4242
import org.springframework.security.oauth2.jose.TestKeys;
43+
import org.springframework.security.oauth2.jwt.JwtClaimNames;
4344

4445
import static org.assertj.core.api.Assertions.assertThat;
4546
import static org.assertj.core.api.Assertions.assertThatCode;
47+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4648
import static org.mockito.Mockito.mock;
4749
import static org.springframework.security.oauth2.jwt.JwtClaimNames.ISS;
4850

@@ -85,6 +87,31 @@ public void resolveWhenUsingTrustedIssuerThenReturnsAuthenticationManager() thro
8587
}
8688
}
8789

90+
// gh-10444
91+
@Test
92+
public void resolveWhenIssuerFailsThenErrorNotCached() throws Exception {
93+
try (MockWebServer server = new MockWebServer()) {
94+
String issuer = server.url("").toString();
95+
// @formatter:off
96+
server.enqueue(new MockResponse().setResponseCode(500).setHeader("Content-Type", "application/json")
97+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer)));
98+
server.enqueue(new MockResponse().setResponseCode(200).setHeader("Content-Type", "application/json")
99+
.setBody(String.format(DEFAULT_RESPONSE_TEMPLATE, issuer, issuer)));
100+
// @formatter:on
101+
JWSObject jws = new JWSObject(new JWSHeader(JWSAlgorithm.RS256),
102+
new Payload(new JSONObject(Collections.singletonMap(JwtClaimNames.ISS, issuer))));
103+
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
104+
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerReactiveAuthenticationManagerResolver(
105+
issuer);
106+
MockServerWebExchange exchange = withBearerToken(jws.serialize());
107+
assertThatExceptionOfType(IllegalArgumentException.class)
108+
.isThrownBy(() -> authenticationManagerResolver.resolve(exchange).block());
109+
ReactiveAuthenticationManager authenticationManager = authenticationManagerResolver.resolve(exchange)
110+
.block();
111+
assertThat(authenticationManager).isNotNull();
112+
}
113+
}
114+
88115
@Test
89116
public void resolveWhenUsingUntrustedIssuerThenException() {
90117
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver =

0 commit comments

Comments
 (0)