浏览代码

Merge branch '6.4.x'

Josh Cummings 3 月之前
父节点
当前提交
fe6ddd0c8f

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 the original author or authors.
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 package org.springframework.security.oauth2.client.registration;
 package org.springframework.security.oauth2.client.registration;
 
 
 import java.net.URI;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
@@ -49,6 +50,7 @@ import org.springframework.web.util.UriComponentsBuilder;
  * @author Rob Winch
  * @author Rob Winch
  * @author Josh Cummings
  * @author Josh Cummings
  * @author Rafiullah Hamedy
  * @author Rafiullah Hamedy
+ * @author Evgeniy Cheban
  * @since 5.1
  * @since 5.1
  */
  */
 public final class ClientRegistrations {
 public final class ClientRegistrations {
@@ -265,6 +267,7 @@ public final class ClientRegistrations {
 	private static ClientRegistration.Builder getBuilder(String issuer,
 	private static ClientRegistration.Builder getBuilder(String issuer,
 			Supplier<ClientRegistration.Builder>... suppliers) {
 			Supplier<ClientRegistration.Builder>... suppliers) {
 		String errorMessage = "Unable to resolve Configuration with the provided Issuer of \"" + issuer + "\"";
 		String errorMessage = "Unable to resolve Configuration with the provided Issuer of \"" + issuer + "\"";
+		List<String> errors = new ArrayList<>();
 		for (Supplier<ClientRegistration.Builder> supplier : suppliers) {
 		for (Supplier<ClientRegistration.Builder> supplier : suppliers) {
 			try {
 			try {
 				return supplier.get();
 				return supplier.get();
@@ -273,6 +276,7 @@ public final class ClientRegistrations {
 				if (!ex.getStatusCode().is4xxClientError()) {
 				if (!ex.getStatusCode().is4xxClientError()) {
 					throw ex;
 					throw ex;
 				}
 				}
+				errors.add(ex.getMessage());
 				// else try another endpoint
 				// else try another endpoint
 			}
 			}
 			catch (IllegalArgumentException | IllegalStateException ex) {
 			catch (IllegalArgumentException | IllegalStateException ex) {
@@ -282,6 +286,9 @@ public final class ClientRegistrations {
 				throw new IllegalArgumentException(errorMessage, ex);
 				throw new IllegalArgumentException(errorMessage, ex);
 			}
 			}
 		}
 		}
+		if (!errors.isEmpty()) {
+			throw new IllegalArgumentException(errorMessage + ", errors: " + errors);
+		}
 		throw new IllegalArgumentException(errorMessage);
 		throw new IllegalArgumentException(errorMessage);
 	}
 	}
 
 

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2025 the original author or authors.
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
@@ -37,12 +37,14 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
 import org.springframework.web.util.UriComponents;
 import org.springframework.web.util.UriComponents;
 
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 
 
 /**
 /**
  * @author Rob Winch
  * @author Rob Winch
  * @author Rafiullah Hamedy
  * @author Rafiullah Hamedy
+ * @author Evgeniy Cheban
  * @since 5.1
  * @since 5.1
  */
  */
 public class ClientRegistrationsTests {
 public class ClientRegistrationsTests {
@@ -581,6 +583,33 @@ public class ClientRegistrationsTests {
 		assertThat(oidcRfc8414.getHost()).isEqualTo("elated_sutherland");
 		assertThat(oidcRfc8414.getHost()).isEqualTo("elated_sutherland");
 	}
 	}
 
 
+	@Test
+	public void issuerWhenAllEndpointsFailedThenExceptionIncludesFailureInformation() {
+		this.issuer = createIssuerFromServer("issuer1");
+		this.server.setDispatcher(new Dispatcher() {
+			@Override
+			public MockResponse dispatch(RecordedRequest request) {
+				int responseCode = switch (request.getPath()) {
+					case "/issuer1/.well-known/openid-configuration" -> 405;
+					case "/.well-known/openid-configuration/issuer1" -> 400;
+					default -> 404;
+				};
+				return new MockResponse().setResponseCode(responseCode);
+			}
+		});
+		String message = """
+				Unable to resolve Configuration with the provided Issuer of "%s", errors: [\
+				405 Client Error on GET request for "%s": [no body], \
+				400 Client Error on GET request for "%s": [no body], \
+				404 Client Error on GET request for "%s": [no body]]\
+				""".formatted(this.issuer, this.server.url("/issuer1/.well-known/openid-configuration"),
+				this.server.url("/.well-known/openid-configuration/issuer1"),
+				this.server.url("/.well-known/oauth-authorization-server/issuer1"));
+		assertThatExceptionOfType(IllegalArgumentException.class)
+			.isThrownBy(() -> ClientRegistrations.fromIssuerLocation(this.issuer).build())
+			.withMessage(message);
+	}
+
 	private ClientRegistration.Builder registration(String path) throws Exception {
 	private ClientRegistration.Builder registration(String path) throws Exception {
 		this.issuer = createIssuerFromServer(path);
 		this.issuer = createIssuerFromServer(path);
 		this.response.put("issuer", this.issuer);
 		this.response.put("issuer", this.issuer);