Explorar o código

Polish gh-946

Joe Grandja %!s(int64=2) %!d(string=hai) anos
pai
achega
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]]
 [[oidc-client-registration-endpoint]]
 == OpenID Connect 1.0 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]
 [source,java]
 ----
 ----
@@ -375,18 +377,18 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
 						.authenticationProviders(authenticationProvidersConsumer) <4>
 						.authenticationProviders(authenticationProvidersConsumer) <4>
 						.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
 						.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
 						.errorResponseHandler(errorResponseHandler) <6>
 						.errorResponseHandler(errorResponseHandler) <6>
-            )
+				)
 		);
 		);
 
 
 	return http.build();
 	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`.
 <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`.
 <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`.
 <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]
 [NOTE]
 The OpenID Connect 1.0 Client Registration endpoint is disabled by default because many deployments do not require dynamic client registration.
 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`.
 * `*AuthenticationConverter*` -- An `OidcClientRegistrationAuthenticationConverter`.
 * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
 * `*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.
 * `*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.
 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.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
 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.OidcClientConfigurationAuthenticationProvider;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
 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.authentication.OidcClientRegistrationAuthenticationToken;
@@ -46,7 +46,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 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 Joe Grandja
  * @author Daniel Garnier-Moiroux
  * @author Daniel Garnier-Moiroux
@@ -57,7 +57,7 @@ import org.springframework.util.Assert;
 public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAuth2Configurer {
 public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAuth2Configurer {
 	private RequestMatcher requestMatcher;
 	private RequestMatcher requestMatcher;
 	private final List<AuthenticationConverter> clientRegistrationRequestConverters = new ArrayList<>();
 	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 final List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
 	private Consumer<List<AuthenticationProvider>> authenticationProvidersConsumer = (authenticationProviders) -> {};
 	private Consumer<List<AuthenticationProvider>> authenticationProvidersConsumer = (authenticationProviders) -> {};
 	private AuthenticationSuccessHandler clientRegistrationResponseHandler;
 	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
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 * @since 0.4.0
 	 */
 	 */
@@ -96,16 +94,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	 * @return the {@link OidcUserInfoEndpointConfigurer} for further configuration
 	 * @return the {@link OidcUserInfoEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 * @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");
 		Assert.notNull(clientRegistrationRequestConvertersConsumer, "clientRegistrationRequestConvertersConsumer cannot be null");
 		this.clientRegistrationRequestConvertersConsumer = clientRegistrationRequestConvertersConsumer;
 		this.clientRegistrationRequestConvertersConsumer = clientRegistrationRequestConvertersConsumer;
 		return this;
 		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
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @since 0.4.0
 	 * @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}
 	 * @param clientRegistrationResponseHandler the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @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}
 	 * @param errorResponseHandler the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
 	 * @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
@@ -160,18 +159,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 	@Override
 	@Override
 	void init(HttpSecurity httpSecurity) {
 	void init(HttpSecurity httpSecurity) {
 		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
 		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
+		String clientRegistrationEndpointUri = authorizationServerSettings.getOidcClientRegistrationEndpoint();
 		this.requestMatcher = new OrRequestMatcher(
 		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);
 		List<AuthenticationProvider> authenticationProviders = createDefaultAuthenticationProviders(httpSecurity);
-
 		if (!this.authenticationProviders.isEmpty()) {
 		if (!this.authenticationProviders.isEmpty()) {
 			authenticationProviders.addAll(0, this.authenticationProviders);
 			authenticationProviders.addAll(0, this.authenticationProviders);
 		}
 		}
 		this.authenticationProvidersConsumer.accept(authenticationProviders);
 		this.authenticationProvidersConsumer.accept(authenticationProviders);
-
 		authenticationProviders.forEach(authenticationProvider ->
 		authenticationProviders.forEach(authenticationProvider ->
 				httpSecurity.authenticationProvider(postProcess(authenticationProvider)));
 				httpSecurity.authenticationProvider(postProcess(authenticationProvider)));
 	}
 	}
@@ -185,7 +183,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 				new OidcClientRegistrationEndpointFilter(
 				new OidcClientRegistrationEndpointFilter(
 						authenticationManager,
 						authenticationManager,
 						authorizationServerSettings.getOidcClientRegistrationEndpoint());
 						authorizationServerSettings.getOidcClientRegistrationEndpoint());
-
 		List<AuthenticationConverter> authenticationConverters = createDefaultAuthenticationConverters();
 		List<AuthenticationConverter> authenticationConverters = createDefaultAuthenticationConverters();
 		if (!this.clientRegistrationRequestConverters.isEmpty()) {
 		if (!this.clientRegistrationRequestConverters.isEmpty()) {
 			authenticationConverters.addAll(0, this.clientRegistrationRequestConverters);
 			authenticationConverters.addAll(0, this.clientRegistrationRequestConverters);
@@ -193,7 +190,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 		this.clientRegistrationRequestConvertersConsumer.accept(authenticationConverters);
 		this.clientRegistrationRequestConvertersConsumer.accept(authenticationConverters);
 		oidcClientRegistrationEndpointFilter.setAuthenticationConverter(
 		oidcClientRegistrationEndpointFilter.setAuthenticationConverter(
 				new DelegatingAuthenticationConverter(authenticationConverters));
 				new DelegatingAuthenticationConverter(authenticationConverters));
-
 		if (this.clientRegistrationResponseHandler != null) {
 		if (this.clientRegistrationResponseHandler != null) {
 			oidcClientRegistrationEndpointFilter
 			oidcClientRegistrationEndpointFilter
 					.setAuthenticationSuccessHandler(this.clientRegistrationResponseHandler);
 					.setAuthenticationSuccessHandler(this.clientRegistrationResponseHandler);
@@ -209,6 +205,14 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 		return this.requestMatcher;
 		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) {
 	private static List<AuthenticationProvider> createDefaultAuthenticationProviders(HttpSecurity httpSecurity) {
 		List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
 		List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
 
 
@@ -224,13 +228,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
 						OAuth2ConfigurerUtils.getRegisteredClientRepository(httpSecurity),
 						OAuth2ConfigurerUtils.getRegisteredClientRepository(httpSecurity),
 						OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity));
 						OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity));
 		authenticationProviders.add(oidcClientConfigurationAuthenticationProvider);
 		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 AuthenticationManager authenticationManager;
 	private final RequestMatcher clientRegistrationEndpointMatcher;
 	private final RequestMatcher clientRegistrationEndpointMatcher;
-	private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
 	private final HttpMessageConverter<OidcClientRegistration> clientRegistrationHttpMessageConverter =
 	private final HttpMessageConverter<OidcClientRegistration> clientRegistrationHttpMessageConverter =
 			new OidcClientRegistrationHttpMessageConverter();
 			new OidcClientRegistrationHttpMessageConverter();
 	private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
 	private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
 			new OAuth2ErrorHttpMessageConverter();
 			new OAuth2ErrorHttpMessageConverter();
+	private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
 	private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendClientRegistrationResponse;
 	private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendClientRegistrationResponse;
 	private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
 	private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
 
 
@@ -130,11 +130,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		}
 		}
 
 
 		try {
 		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);
 			this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
 		} catch (OAuth2AuthenticationException ex) {
 		} catch (OAuth2AuthenticationException ex) {
@@ -142,7 +141,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		} catch (Exception ex) {
 		} catch (Exception ex) {
 			OAuth2Error error = new OAuth2Error(
 			OAuth2Error error = new OAuth2Error(
 					OAuth2ErrorCodes.INVALID_REQUEST,
 					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");
 					"https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError");
 			this.authenticationFailureHandler.onAuthenticationFailure(request, response,
 			this.authenticationFailureHandler.onAuthenticationFailure(request, response,
 					new OAuth2AuthenticationException(error));
 					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
 	 * @since 0.4.0
 	 */
 	 */
 	public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
 	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
 	 * @since 0.4.0
 	 */
 	 */
 	public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
 	public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
@@ -197,8 +193,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
 		ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
 		ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
 		if (HttpMethod.POST.name().equals(request.getMethod())) {
 		if (HttpMethod.POST.name().equals(request.getMethod())) {
 			httpResponse.setStatusCode(HttpStatus.CREATED);
 			httpResponse.setStatusCode(HttpStatus.CREATED);
-		}
-		else {
+		} else {
 			httpResponse.setStatusCode(HttpStatus.OK);
 			httpResponse.setStatusCode(HttpStatus.OK);
 		}
 		}
 		this.clientRegistrationHttpMessageConverter.write(clientRegistration, null, httpResponse);
 		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.OidcClientRegistrationAuthenticationProvider;
 import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
 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.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.AuthorizationServerSettings;
 import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
 import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
 import org.springframework.security.oauth2.server.authorization.test.SpringTestRule;
 import org.springframework.security.oauth2.server.authorization.test.SpringTestRule;
@@ -308,7 +309,7 @@ public class OidcClientRegistrationTests {
 	}
 	}
 
 
 	@Test
 	@Test
-	public void requestWhenUserInfoEndpointCustomizedThenUsed() throws Exception {
+	public void requestWhenClientRegistrationEndpointCustomizedThenUsed() throws Exception {
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 
 
 		// @formatter:off
 		// @formatter:off
@@ -333,15 +334,17 @@ public class OidcClientRegistrationTests {
 		registerClient(clientRegistration);
 		registerClient(clientRegistration);
 
 
 		verify(authenticationConverter).convert(any());
 		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());
 		verify(authenticationConvertersConsumer).accept(authenticationConvertersCaptor.capture());
 		List<AuthenticationConverter> authenticationConverters = authenticationConvertersCaptor.getValue();
 		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());
 		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());
 		verify(authenticationProvidersConsumer).accept(authenticationProvidersCaptor.capture());
 		List<AuthenticationProvider> authenticationProviders = authenticationProvidersCaptor.getValue();
 		List<AuthenticationProvider> authenticationProviders = authenticationProvidersCaptor.getValue();
 		assertThat(authenticationProviders).hasSize(3)
 		assertThat(authenticationProviders).hasSize(3)
@@ -354,7 +357,7 @@ public class OidcClientRegistrationTests {
 	}
 	}
 
 
 	@Test
 	@Test
-	public void requestWhenUserInfoEndpointCustomizedAndErrorThenUsed() throws Exception {
+	public void requestWhenClientRegistrationEndpointCustomizedWithAuthenticationFailureHandlerThenUsed() throws Exception {
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 		this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
 
 
 		when(authenticationProvider.authenticate(any())).thenThrow(new OAuth2AuthenticationException("error"));
 		when(authenticationProvider.authenticate(any())).thenThrow(new OAuth2AuthenticationException("error"));
@@ -461,27 +464,38 @@ public class OidcClientRegistrationTests {
 	@EnableWebSecurity
 	@EnableWebSecurity
 	static class CustomClientRegistrationConfiguration extends AuthorizationServerConfiguration {
 	static class CustomClientRegistrationConfiguration extends AuthorizationServerConfiguration {
 
 
+		// @formatter:off
 		@Bean
 		@Bean
 		@Override
 		@Override
 		public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 		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();
 			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))
 					.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt).apply(authorizationServerConfigurer);
+					.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
+					.apply(authorizationServerConfigurer);
 			return http.build();
 			return http.build();
-
 		}
 		}
-
+		// @formatter:on
 	}
 	}
 
 
 	@EnableWebSecurity
 	@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);
 				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(
 	private void doFilterWhenClientConfigurationRequestInvalidThenError(
 			String errorCode, HttpStatus status) throws Exception {
 			String errorCode, HttpStatus status) throws Exception {
 		Jwt jwt = createJwt("client.read");
 		Jwt jwt = createJwt("client.read");
@@ -475,6 +454,24 @@ public class OidcClientRegistrationEndpointFilterTests {
 				.isEqualTo(expectedClientRegistrationResponse.getRegistrationClientUrl());
 				.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
 	@Test
 	public void doFilterWhenCustomAuthenticationSuccessHandlerThenUsed() throws Exception {
 	public void doFilterWhenCustomAuthenticationSuccessHandlerThenUsed() throws Exception {
 		OidcClientRegistration expectedClientRegistrationResponse = createClientRegistration();
 		OidcClientRegistration expectedClientRegistrationResponse = createClientRegistration();
@@ -504,43 +501,25 @@ public class OidcClientRegistrationEndpointFilterTests {
 		verify(successHandler).onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
 		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
 	@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;
 		String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
 		request.setServletPath(requestUri);
 		request.setServletPath(requestUri);
-		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client-id");
-
+		request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client1");
 		MockHttpServletResponse response = new MockHttpServletResponse();
 		MockHttpServletResponse response = new MockHttpServletResponse();
 		FilterChain filterChain = mock(FilterChain.class);
 		FilterChain filterChain = mock(FilterChain.class);
 
 
 		this.filter.doFilter(request, response, filterChain);
 		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 {
 	private OAuth2Error readError(MockHttpServletResponse response) throws Exception {
@@ -562,6 +541,27 @@ public class OidcClientRegistrationEndpointFilterTests {
 		return this.clientRegistrationHttpMessageConverter.read(OidcClientRegistration.class, httpResponse);
 		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) {
 	private static Jwt createJwt(String scope) {
 		// @formatter:off
 		// @formatter:off
 		JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()
 		JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()