Joe Grandja 2 жил өмнө
parent
commit
bfd7a09c3b

+ 9 - 7
docs/src/docs/asciidoc/protocol-endpoints.adoc

@@ -353,8 +353,10 @@ The guide xref:guides/how-to-userinfo.adoc#how-to-userinfo[How-to: Customize the
 [[oidc-client-registration-endpoint]]
 == OpenID Connect 1.0 Client Registration Endpoint
 
-`OidcClientRegistrationEndpointConfigurer` configures the https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OpenID Connect 1.0 Client Registration endpoint].
-The following example shows how to enable (disabled by default) the OpenID Connect 1.0 Client Registration endpoint:
+`OidcClientRegistrationEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OpenID Connect 1.0 Client Registration endpoint].
+It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration requests] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read requests].
+
+`OidcClientRegistrationEndpointConfigurer` provides the following configuration options:
 
 [source,java]
 ----
@@ -375,18 +377,18 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
 						.authenticationProviders(authenticationProvidersConsumer) <4>
 						.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
 						.errorResponseHandler(errorResponseHandler) <6>
-            )
+				)
 		);
 
 	return http.build();
 }
 ----
-<1> `clientRegistrationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration Request] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read Request] from `HttpServletRequest` to an instance of `OidcClientRegistrationAuthenticationToken`.
+<1> `clientRegistrationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration request] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read request] from `HttpServletRequest` to an instance of `OidcClientRegistrationAuthenticationToken`.
 <2> `clientRegistrationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
 <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcClientRegistrationAuthenticationToken`.
 <4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
-<5> `clientRegistrationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration Response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read Response].
-<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError[Client Registration Error Response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadError[Client Read Error Response].
+<5> `clientRegistrationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read response].
+<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError[Client Registration Error response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadError[Client Read Error response].
 
 [NOTE]
 The OpenID Connect 1.0 Client Registration endpoint is disabled by default because many deployments do not require dynamic client registration.
@@ -401,7 +403,7 @@ The OpenID Connect 1.0 Client Registration endpoint is disabled by default becau
 
 * `*AuthenticationConverter*` -- An `OidcClientRegistrationAuthenticationConverter`.
 * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
-* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the Client Registration or Client Read response.
+* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the `OidcClientRegistration` response.
 * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
 
 The OpenID Connect 1.0 Client Registration endpoint is an https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OAuth2 protected resource], which *REQUIRES* an access token to be sent as a bearer token in the Client Registration (or Client Read) request.

+ 26 - 27
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationEndpointConfigurer.java

@@ -28,7 +28,7 @@ import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
-import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
+import org.springframework.security.oauth2.server.authorization.oidc.OidcClientRegistration;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientConfigurationAuthenticationProvider;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
@@ -46,7 +46,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 
 /**
- * Configurer for OpenID Connect Dynamic Client Registration 1.0 Endpoint.
+ * Configurer for OpenID Connect 1.0 Dynamic Client Registration Endpoint.
  *
  * @author Joe Grandja
  * @author Daniel Garnier-Moiroux
@@ -57,7 +57,7 @@ import org.springframework.util.Assert;
 public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAuth2Configurer {
 	private RequestMatcher requestMatcher;
 	private final List<AuthenticationConverter> clientRegistrationRequestConverters = new ArrayList<>();
-	private Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer = (authenticationConverters) -> {};
+	private Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer = (clientRegistrationRequestConverters) -> {};
 	private final List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
 	private Consumer<List<AuthenticationProvider>> authenticationProvidersConsumer = (authenticationProviders) -> {};
 	private AuthenticationSuccessHandler clientRegistrationResponseHandler;
@@ -71,12 +71,10 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	}
 
 	/**
-	 * Sets the {@link AuthenticationConverter} used when attempting to extract the OIDC Client Registration Request
-	 * from {@link HttpServletRequest} to an instance of {@link OidcClientRegistrationAuthenticationToken} used for
-	 * creating the Client Registration or returning the Client Read Response.
+	 * Adds an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
+	 * to an instance of {@link OidcClientRegistrationAuthenticationToken} used for authenticating the request.
 	 *
-	 * @param clientRegistrationRequestConverter the {@link AuthenticationConverter} used when attempting to extract an
-	 * OIDC Client Registration Request from {@link HttpServletRequest}
+	 * @param clientRegistrationRequestConverter an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 */
@@ -96,16 +94,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	 * @return the {@link OidcUserInfoEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 */
-	public OidcClientRegistrationEndpointConfigurer clientRegistrationRequestConverters(Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer) {
+	public OidcClientRegistrationEndpointConfigurer clientRegistrationRequestConverters(
+			Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer) {
 		Assert.notNull(clientRegistrationRequestConvertersConsumer, "clientRegistrationRequestConvertersConsumer cannot be null");
 		this.clientRegistrationRequestConvertersConsumer = clientRegistrationRequestConvertersConsumer;
 		return this;
 	}
 
 	/**
-	 * Adds an {@link AuthenticationProvider} used for authenticating a type of {@link OidcClientRegistrationAuthenticationToken}.
+	 * Adds an {@link AuthenticationProvider} used for authenticating an {@link OidcClientRegistrationAuthenticationToken}.
 	 *
-	 * @param authenticationProvider a {@link AuthenticationProvider} used for authenticating a type of {@link OidcClientRegistrationAuthenticationToken}
+	 * @param authenticationProvider an {@link AuthenticationProvider} used for authenticating an {@link OidcClientRegistrationAuthenticationToken}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 */
@@ -132,8 +131,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	}
 
 	/**
-	 * Sets the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken} and
-	 * returning the {@link OidcUserInfo User Info Response}.
+	 * Sets the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken}
+	 * and returning the {@link OidcClientRegistration Client Registration Response}.
 	 *
 	 * @param clientRegistrationResponseHandler the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
@@ -145,8 +144,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	}
 
 	/**
-	 * Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException} and
-	 * returning the {@link OAuth2Error Error Response}.
+	 * Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
+	 * and returning the {@link OAuth2Error Error Response}.
 	 *
 	 * @param errorResponseHandler the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
@@ -160,18 +159,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	@Override
 	void init(HttpSecurity httpSecurity) {
 		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
+		String clientRegistrationEndpointUri = authorizationServerSettings.getOidcClientRegistrationEndpoint();
 		this.requestMatcher = new OrRequestMatcher(
-				new AntPathRequestMatcher(authorizationServerSettings.getOidcClientRegistrationEndpoint(), HttpMethod.POST.name()),
-				new AntPathRequestMatcher(authorizationServerSettings.getOidcClientRegistrationEndpoint(), HttpMethod.GET.name())
+				new AntPathRequestMatcher(clientRegistrationEndpointUri, HttpMethod.POST.name()),
+				new AntPathRequestMatcher(clientRegistrationEndpointUri, HttpMethod.GET.name())
 		);
 
 		List<AuthenticationProvider> authenticationProviders = createDefaultAuthenticationProviders(httpSecurity);
-
 		if (!this.authenticationProviders.isEmpty()) {
 			authenticationProviders.addAll(0, this.authenticationProviders);
 		}
 		this.authenticationProvidersConsumer.accept(authenticationProviders);
-
 		authenticationProviders.forEach(authenticationProvider ->
 				httpSecurity.authenticationProvider(postProcess(authenticationProvider)));
 	}
@@ -185,7 +183,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 				new OidcClientRegistrationEndpointFilter(
 						authenticationManager,
 						authorizationServerSettings.getOidcClientRegistrationEndpoint());
-
 		List<AuthenticationConverter> authenticationConverters = createDefaultAuthenticationConverters();
 		if (!this.clientRegistrationRequestConverters.isEmpty()) {
 			authenticationConverters.addAll(0, this.clientRegistrationRequestConverters);
@@ -193,7 +190,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 		this.clientRegistrationRequestConvertersConsumer.accept(authenticationConverters);
 		oidcClientRegistrationEndpointFilter.setAuthenticationConverter(
 				new DelegatingAuthenticationConverter(authenticationConverters));
-
 		if (this.clientRegistrationResponseHandler != null) {
 			oidcClientRegistrationEndpointFilter
 					.setAuthenticationSuccessHandler(this.clientRegistrationResponseHandler);
@@ -209,6 +205,14 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 		return this.requestMatcher;
 	}
 
+	private static List<AuthenticationConverter> createDefaultAuthenticationConverters() {
+		List<AuthenticationConverter> authenticationConverters = new ArrayList<>();
+
+		authenticationConverters.add(new OidcClientRegistrationAuthenticationConverter());
+
+		return authenticationConverters;
+	}
+
 	private static List<AuthenticationProvider> createDefaultAuthenticationProviders(HttpSecurity httpSecurity) {
 		List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
 
@@ -224,13 +228,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 						OAuth2ConfigurerUtils.getRegisteredClientRepository(httpSecurity),
 						OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity));
 		authenticationProviders.add(oidcClientConfigurationAuthenticationProvider);
-		return authenticationProviders;
-	}
 
-	private static List<AuthenticationConverter> createDefaultAuthenticationConverters() {
-		List<AuthenticationConverter> authenticationConverters = new ArrayList<>();
-		authenticationConverters.add(new OidcClientRegistrationAuthenticationConverter());
-		return authenticationConverters;
+		return authenticationProviders;
 	}
 
 }

+ 13 - 18
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcClientRegistrationEndpointFilter.java

@@ -74,11 +74,11 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 
 	private final AuthenticationManager authenticationManager;
 	private final RequestMatcher clientRegistrationEndpointMatcher;
-	private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
 	private final HttpMessageConverter<OidcClientRegistration> clientRegistrationHttpMessageConverter =
 			new OidcClientRegistrationHttpMessageConverter();
 	private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
 			new OAuth2ErrorHttpMessageConverter();
+	private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
 	private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendClientRegistrationResponse;
 	private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
 
@@ -130,11 +130,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		}
 
 		try {
-			OidcClientRegistrationAuthenticationToken clientRegistrationAuthentication =
-					(OidcClientRegistrationAuthenticationToken) this.authenticationConverter.convert(request);
+			Authentication clientRegistrationAuthentication = this.authenticationConverter.convert(request);
 
-			OidcClientRegistrationAuthenticationToken clientRegistrationAuthenticationResult =
-					(OidcClientRegistrationAuthenticationToken) this.authenticationManager.authenticate(clientRegistrationAuthentication);
+			Authentication clientRegistrationAuthenticationResult =
+					this.authenticationManager.authenticate(clientRegistrationAuthentication);
 
 			this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
 		} catch (OAuth2AuthenticationException ex) {
@@ -142,7 +141,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		} catch (Exception ex) {
 			OAuth2Error error = new OAuth2Error(
 					OAuth2ErrorCodes.INVALID_REQUEST,
-					"OpenID Client Registration Error: " + ex.getMessage(),
+					"OpenID Connect 1.0 Client Registration Error: " + ex.getMessage(),
 					"https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError");
 			this.authenticationFailureHandler.onAuthenticationFailure(request, response,
 					new OAuth2AuthenticationException(error));
@@ -152,12 +151,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 	}
 
 	/**
-	 * Sets the {@link AuthenticationConverter} used when attempting to extract the OIDC Client Registration Request
-	 * from {@link HttpServletRequest} to an instance of {@link OidcClientRegistrationAuthenticationToken} used for
-	 * creating the Client Registration or returning the Client Read Response.
+	 * Sets the {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
+	 * to an instance of {@link OidcClientRegistrationAuthenticationToken} used for authenticating the request.
 	 *
-	 * @param authenticationConverter the {@link AuthenticationConverter} used when attempting to extract an
-	 * OIDC Client Registration Request from {@link HttpServletRequest}
+	 * @param authenticationConverter an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
 	 * @since 0.4.0
 	 */
 	public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
@@ -178,11 +175,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 	}
 
 	/**
-	 * Sets the {@link AuthenticationFailureHandler} used for handling an
-	 * {@link OAuth2AuthenticationException} and returning the {@link OAuth2Error Error
-	 * Response}.
-	 * @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used
-	 * for handling an {@link OAuth2AuthenticationException}
+	 * Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
+	 * and returning the {@link OAuth2Error Error Response}.
+	 *
+	 * @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
 	 * @since 0.4.0
 	 */
 	public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
@@ -197,8 +193,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
 		if (HttpMethod.POST.name().equals(request.getMethod())) {
 			httpResponse.setStatusCode(HttpStatus.CREATED);
-		}
-		else {
+		} else {
 			httpResponse.setStatusCode(HttpStatus.OK);
 		}
 		this.clientRegistrationHttpMessageConverter.write(clientRegistration, null, httpResponse);

+ 34 - 20
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationTests.java

@@ -88,6 +88,7 @@ import org.springframework.security.oauth2.server.authorization.oidc.authenticat
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
 import org.springframework.security.oauth2.server.authorization.oidc.http.converter.OidcClientRegistrationHttpMessageConverter;
+import org.springframework.security.oauth2.server.authorization.oidc.web.authentication.OidcClientRegistrationAuthenticationConverter;
 import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
 import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
 import org.springframework.security.oauth2.server.authorization.test.SpringTestRule;
@@ -308,7 +309,7 @@ public class OidcClientRegistrationTests {
 	}
 
 	@Test
-	public void requestWhenUserInfoEndpointCustomizedThenUsed() throws Exception {
+	public void requestWhenClientRegistrationEndpointCustomizedThenUsed() throws Exception {
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 
 		// @formatter:off
@@ -333,15 +334,17 @@ public class OidcClientRegistrationTests {
 		registerClient(clientRegistration);
 
 		verify(authenticationConverter).convert(any());
-		ArgumentCaptor<List<AuthenticationConverter>> authenticationConvertersCaptor = ArgumentCaptor
-				.forClass(List.class);
+		ArgumentCaptor<List<AuthenticationConverter>> authenticationConvertersCaptor =
+				ArgumentCaptor.forClass(List.class);
 		verify(authenticationConvertersConsumer).accept(authenticationConvertersCaptor.capture());
 		List<AuthenticationConverter> authenticationConverters = authenticationConvertersCaptor.getValue();
-		assertThat(authenticationConverters).hasSize(2).contains(authenticationConverter);
+		assertThat(authenticationConverters).hasSize(2)
+				.allMatch(converter -> converter == authenticationConverter
+						|| converter instanceof OidcClientRegistrationAuthenticationConverter);
 
 		verify(authenticationProvider).authenticate(any());
-		ArgumentCaptor<List<AuthenticationProvider>> authenticationProvidersCaptor = ArgumentCaptor
-				.forClass(List.class);
+		ArgumentCaptor<List<AuthenticationProvider>> authenticationProvidersCaptor =
+				ArgumentCaptor.forClass(List.class);
 		verify(authenticationProvidersConsumer).accept(authenticationProvidersCaptor.capture());
 		List<AuthenticationProvider> authenticationProviders = authenticationProvidersCaptor.getValue();
 		assertThat(authenticationProviders).hasSize(3)
@@ -354,7 +357,7 @@ public class OidcClientRegistrationTests {
 	}
 
 	@Test
-	public void requestWhenUserInfoEndpointCustomizedAndErrorThenUsed() throws Exception {
+	public void requestWhenClientRegistrationEndpointCustomizedWithAuthenticationFailureHandlerThenUsed() throws Exception {
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 
 		when(authenticationProvider.authenticate(any())).thenThrow(new OAuth2AuthenticationException("error"));
@@ -461,27 +464,38 @@ public class OidcClientRegistrationTests {
 	@EnableWebSecurity
 	static class CustomClientRegistrationConfiguration extends AuthorizationServerConfiguration {
 
+		// @formatter:off
 		@Bean
 		@Override
 		public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer.oidc(oidc -> oidc.clientRegistrationEndpoint(
-					clientRegistration -> clientRegistration.clientRegistrationRequestConverter(authenticationConverter)
-							.clientRegistrationRequestConverters(authenticationConvertersConsumer)
-							.authenticationProvider(authenticationProvider)
-							.authenticationProviders(authenticationProvidersConsumer)
-							.clientRegistrationResponseHandler(authenticationSuccessHandler)
-							.errorResponseHandler(authenticationFailureHandler)));
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					new OAuth2AuthorizationServerConfigurer();
+			authorizationServerConfigurer
+				.oidc(oidc ->
+					oidc
+						.clientRegistrationEndpoint(clientRegistration ->
+							clientRegistration
+								.clientRegistrationRequestConverter(authenticationConverter)
+								.clientRegistrationRequestConverters(authenticationConvertersConsumer)
+								.authenticationProvider(authenticationProvider)
+								.authenticationProviders(authenticationProvidersConsumer)
+								.clientRegistrationResponseHandler(authenticationSuccessHandler)
+								.errorResponseHandler(authenticationFailureHandler)
+						)
+				);
 			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
 
-			http.requestMatcher(endpointsMatcher)
-					.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated())
+			http
+					.requestMatcher(endpointsMatcher)
+					.authorizeRequests(authorizeRequests ->
+							authorizeRequests.anyRequest().authenticated()
+					)
 					.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt).apply(authorizationServerConfigurer);
+					.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
+					.apply(authorizationServerConfigurer);
 			return http.build();
-
 		}
-
+		// @formatter:on
 	}
 
 	@EnableWebSecurity

+ 48 - 48
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcClientRegistrationEndpointFilterTests.java

@@ -371,27 +371,6 @@ public class OidcClientRegistrationEndpointFilterTests {
 				OAuth2ErrorCodes.INVALID_CLIENT, HttpStatus.UNAUTHORIZED);
 	}
 
-	@Test
-	public void doFilterWhenCustomAuthenticationFailureHandlerThenUsed() throws Exception {
-		AuthenticationFailureHandler authenticationFailureHandler = mock(AuthenticationFailureHandler.class);
-		this.filter.setAuthenticationFailureHandler(authenticationFailureHandler);
-
-		when(this.authenticationManager.authenticate(any()))
-				.thenThrow(new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN));
-
-		String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
-		request.setServletPath(requestUri);
-		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client1");
-		MockHttpServletResponse response = new MockHttpServletResponse();
-		FilterChain filterChain = mock(FilterChain.class);
-
-		this.filter.doFilter(request, response, filterChain);
-
-		verify(authenticationFailureHandler).onAuthenticationFailure(eq(request), eq(response),
-				any(OAuth2AuthenticationException.class));
-	}
-
 	private void doFilterWhenClientConfigurationRequestInvalidThenError(
 			String errorCode, HttpStatus status) throws Exception {
 		Jwt jwt = createJwt("client.read");
@@ -475,6 +454,24 @@ public class OidcClientRegistrationEndpointFilterTests {
 				.isEqualTo(expectedClientRegistrationResponse.getRegistrationClientUrl());
 	}
 
+	@Test
+	public void doFilterWhenCustomAuthenticationConverterThenUsed() throws ServletException, IOException {
+		AuthenticationConverter authenticationConverter = mock(AuthenticationConverter.class);
+		this.filter.setAuthenticationConverter(authenticationConverter);
+
+		String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
+		request.setServletPath(requestUri);
+		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client-id");
+
+		MockHttpServletResponse response = new MockHttpServletResponse();
+		FilterChain filterChain = mock(FilterChain.class);
+
+		this.filter.doFilter(request, response, filterChain);
+
+		verify(authenticationConverter).convert(request);
+	}
+
 	@Test
 	public void doFilterWhenCustomAuthenticationSuccessHandlerThenUsed() throws Exception {
 		OidcClientRegistration expectedClientRegistrationResponse = createClientRegistration();
@@ -504,43 +501,25 @@ public class OidcClientRegistrationEndpointFilterTests {
 		verify(successHandler).onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
 	}
 
-	private static OidcClientRegistration createClientRegistration() {
-		// @formatter:off
-		OidcClientRegistration expectedClientRegistrationResponse = OidcClientRegistration.builder()
-				.clientId("client-id")
-				.clientIdIssuedAt(Instant.now())
-				.clientSecret("client-secret")
-				.clientName("client-name")
-				.redirectUri("https://client.example.com")
-				.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
-				.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
-				.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
-				.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
-				.idTokenSignedResponseAlgorithm(SignatureAlgorithm.RS256.getName())
-				.scope("scope1")
-				.scope("scope2")
-				.registrationClientUrl("https://auth-server:9000/connect/register?client_id=client-id")
-				.build();
-		return expectedClientRegistrationResponse;
-		// @formatter:on
-	}
-
 	@Test
-	public void doFilterWhenCustomAuthenticationConverterThenUsed() throws ServletException, IOException {
-		AuthenticationConverter authenticationConverter = mock(AuthenticationConverter.class);
-		this.filter.setAuthenticationConverter(authenticationConverter);
+	public void doFilterWhenCustomAuthenticationFailureHandlerThenUsed() throws Exception {
+		AuthenticationFailureHandler authenticationFailureHandler = mock(AuthenticationFailureHandler.class);
+		this.filter.setAuthenticationFailureHandler(authenticationFailureHandler);
+
+		when(this.authenticationManager.authenticate(any()))
+				.thenThrow(new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN));
 
 		String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
 		request.setServletPath(requestUri);
-		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client-id");
-
+		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client1");
 		MockHttpServletResponse response = new MockHttpServletResponse();
 		FilterChain filterChain = mock(FilterChain.class);
 
 		this.filter.doFilter(request, response, filterChain);
 
-		verify(authenticationConverter).convert(request);
+		verify(authenticationFailureHandler).onAuthenticationFailure(eq(request), eq(response),
+				any(OAuth2AuthenticationException.class));
 	}
 
 	private OAuth2Error readError(MockHttpServletResponse response) throws Exception {
@@ -562,6 +541,27 @@ public class OidcClientRegistrationEndpointFilterTests {
 		return this.clientRegistrationHttpMessageConverter.read(OidcClientRegistration.class, httpResponse);
 	}
 
+	private static OidcClientRegistration createClientRegistration() {
+		// @formatter:off
+		OidcClientRegistration clientRegistration = OidcClientRegistration.builder()
+				.clientId("client-id")
+				.clientIdIssuedAt(Instant.now())
+				.clientSecret("client-secret")
+				.clientName("client-name")
+				.redirectUri("https://client.example.com")
+				.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
+				.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
+				.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
+				.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
+				.idTokenSignedResponseAlgorithm(SignatureAlgorithm.RS256.getName())
+				.scope("scope1")
+				.scope("scope2")
+				.registrationClientUrl("https://auth-server:9000/connect/register?client_id=client-id")
+				.build();
+		return clientRegistration;
+		// @formatter:on
+	}
+
 	private static Jwt createJwt(String scope) {
 		// @formatter:off
 		JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()