Skip to content

Commit 0e84f31

Browse files
evgeniychebanjzheaux
authored andcommitted
Add ClientRegistration's RestClient failed attempts information to exception message
Closes gh-16860 Signed-off-by: Evgeniy Cheban <mister.cheban@gmail.com>
1 parent 9c76ab6 commit 0e84f31

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.security.oauth2.client.registration;
1818

1919
import java.net.URI;
20+
import java.util.ArrayList;
2021
import java.util.Collections;
2122
import java.util.LinkedHashMap;
2223
import java.util.List;
@@ -49,6 +50,7 @@
4950
* @author Rob Winch
5051
* @author Josh Cummings
5152
* @author Rafiullah Hamedy
53+
* @author Evgeniy Cheban
5254
* @since 5.1
5355
*/
5456
public final class ClientRegistrations {
@@ -211,6 +213,7 @@ private static Supplier<ClientRegistration.Builder> getRfc8414Builder(URI issuer
211213
private static ClientRegistration.Builder getBuilder(String issuer,
212214
Supplier<ClientRegistration.Builder>... suppliers) {
213215
String errorMessage = "Unable to resolve Configuration with the provided Issuer of \"" + issuer + "\"";
216+
List<String> errors = new ArrayList<>();
214217
for (Supplier<ClientRegistration.Builder> supplier : suppliers) {
215218
try {
216219
return supplier.get();
@@ -219,6 +222,7 @@ private static ClientRegistration.Builder getBuilder(String issuer,
219222
if (!ex.getStatusCode().is4xxClientError()) {
220223
throw ex;
221224
}
225+
errors.add(ex.getMessage());
222226
// else try another endpoint
223227
}
224228
catch (IllegalArgumentException | IllegalStateException ex) {
@@ -228,6 +232,9 @@ private static ClientRegistration.Builder getBuilder(String issuer,
228232
throw new IllegalArgumentException(errorMessage, ex);
229233
}
230234
}
235+
if (!errors.isEmpty()) {
236+
throw new IllegalArgumentException(errorMessage + ", errors: " + errors);
237+
}
231238
throw new IllegalArgumentException(errorMessage);
232239
}
233240

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,12 +36,14 @@
3636
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3737

3838
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3940
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
4041
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
4142

4243
/**
4344
* @author Rob Winch
4445
* @author Rafiullah Hamedy
46+
* @author Evgeniy Cheban
4547
* @since 5.1
4648
*/
4749
public class ClientRegistrationsTests {
@@ -455,6 +457,31 @@ public void issuerWhenOAuth2ConfigurationDoesNotMatchThenMeaningfulErrorMessage(
455457
// @formatter:on
456458
}
457459

460+
@Test
461+
public void issuerWhenAllEndpointsFailedThenExceptionIncludesFailureInformation() {
462+
this.issuer = createIssuerFromServer("issuer1");
463+
this.server.setDispatcher(new Dispatcher() {
464+
@Override
465+
public MockResponse dispatch(RecordedRequest request) {
466+
int responseCode = switch (request.getPath()) {
467+
case "/issuer1/.well-known/openid-configuration" -> 405;
468+
case "/.well-known/openid-configuration/issuer1" -> 400;
469+
default -> 404;
470+
};
471+
return new MockResponse().setResponseCode(responseCode);
472+
}
473+
});
474+
String message = """
475+
Unable to resolve Configuration with the provided Issuer of "%s", errors: [\
476+
405 Client Error: [no body], \
477+
400 Client Error: [no body], \
478+
404 Client Error: [no body]]\
479+
""".formatted(this.issuer);
480+
assertThatExceptionOfType(IllegalArgumentException.class)
481+
.isThrownBy(() -> ClientRegistrations.fromIssuerLocation(this.issuer).build())
482+
.withMessage(message);
483+
}
484+
458485
private ClientRegistration.Builder registration(String path) throws Exception {
459486
this.issuer = createIssuerFromServer(path);
460487
this.response.put("issuer", this.issuer);

0 commit comments

Comments
 (0)