Pārlūkot izejas kodu

Simplify configuring authorization server using HttpSecurity.with()

Closes gh-1707
Joe Grandja 11 mēneši atpakaļ
vecāks
revīzija
2c7975485f
25 mainītis faili ar 751 papildinājumiem un 726 dzēšanām
  1. 66 54
      docs/modules/ROOT/pages/configuration-model.adoc
  2. 33 25
      docs/modules/ROOT/pages/core-model-components.adoc
  3. 3 4
      docs/modules/ROOT/pages/guides/how-to-userinfo.adoc
  4. 209 209
      docs/modules/ROOT/pages/protocol-endpoints.adoc
  5. 14 20
      docs/src/main/java/sample/extgrant/SecurityConfig.java
  6. 10 8
      docs/src/main/java/sample/gettingstarted/SecurityConfig.java
  7. 11 9
      docs/src/main/java/sample/pkce/SecurityConfig.java
  8. 17 11
      docs/src/main/java/sample/registration/SecurityConfig.java
  9. 10 8
      docs/src/main/java/sample/sociallogin/SecurityConfig.java
  10. 9 5
      docs/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java
  11. 16 22
      docs/src/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java
  12. 8 7
      docs/src/test/java/sample/jpa/JpaTests.java
  13. 28 13
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java
  14. 26 1
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerConfigurer.java
  15. 35 44
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java
  16. 9 15
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerMetadataTests.java
  17. 28 33
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ClientCredentialsGrantTests.java
  18. 12 16
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2RefreshTokenGrantTests.java
  19. 14 17
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenIntrospectionTests.java
  20. 14 17
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenRevocationTests.java
  21. 41 55
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationTests.java
  22. 44 26
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java
  23. 26 31
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java
  24. 41 54
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcUserInfoTests.java
  25. 27 22
      samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

+ 66 - 54
docs/modules/ROOT/pages/configuration-model.adoc

@@ -8,9 +8,6 @@
 
 `OAuth2AuthorizationServerConfiguration` uses xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`] to apply the default configuration and registers a `SecurityFilterChain` `@Bean` composed of all the infrastructure components supporting an OAuth2 authorization server.
 
-[TIP]
-`OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)` is a convenience (`static`) utility method that applies the default OAuth2 security configuration to `HttpSecurity`.
-
 The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following default protocol endpoints:
 
 * xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint]
@@ -58,11 +55,14 @@ https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] is dis
 ----
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-	OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-
-	http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-		.oidc(Customizer.withDefaults());	// Initialize `OidcConfigurer`
-
+	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.oidc(Customizer.withDefaults())	// Initialize `OidcConfigurer`
+		);
 	return http.build();
 }
 ----
@@ -105,28 +105,31 @@ Furthermore, it lets you customize the request processing logic for the protocol
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.registeredClientRepository(registeredClientRepository) <1>
-		.authorizationService(authorizationService) <2>
-		.authorizationConsentService(authorizationConsentService)   <3>
-		.authorizationServerSettings(authorizationServerSettings) <4>
-		.tokenGenerator(tokenGenerator) <5>
-		.clientAuthentication(clientAuthentication -> { })  <6>
-		.authorizationEndpoint(authorizationEndpoint -> { })    <7>
-		.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { })    <8>
-		.deviceVerificationEndpoint(deviceVerificationEndpoint -> { })  <9>
-		.tokenEndpoint(tokenEndpoint -> { })    <10>
-		.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { })  <11>
-		.tokenRevocationEndpoint(tokenRevocationEndpoint -> { })    <12>
-		.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { })    <13>
-		.oidc(oidc -> oidc
-			.providerConfigurationEndpoint(providerConfigurationEndpoint -> { })    <14>
-			.logoutEndpoint(logoutEndpoint -> { })  <15>
-			.userInfoEndpoint(userInfoEndpoint -> { })  <16>
-			.clientRegistrationEndpoint(clientRegistrationEndpoint -> { })  <17>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.registeredClientRepository(registeredClientRepository)	<1>
+				.authorizationService(authorizationService)	<2>
+				.authorizationConsentService(authorizationConsentService)	<3>
+				.authorizationServerSettings(authorizationServerSettings)	<4>
+				.tokenGenerator(tokenGenerator)	<5>
+				.clientAuthentication(clientAuthentication -> { })	<6>
+				.authorizationEndpoint(authorizationEndpoint -> { })	<7>
+				.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { })	<8>
+				.deviceVerificationEndpoint(deviceVerificationEndpoint -> { })	<9>
+				.tokenEndpoint(tokenEndpoint -> { })	<10>
+				.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { })	<11>
+				.tokenRevocationEndpoint(tokenRevocationEndpoint -> { })	<12>
+				.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { })	<13>
+				.oidc(oidc -> oidc
+					.providerConfigurationEndpoint(providerConfigurationEndpoint -> { })	<14>
+					.logoutEndpoint(logoutEndpoint -> { })	<15>
+					.userInfoEndpoint(userInfoEndpoint -> { })	<16>
+					.clientRegistrationEndpoint(clientRegistrationEndpoint -> { })	<17>
+				)
 		);
 
 	return http.build();
@@ -232,18 +235,21 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.clientAuthentication(clientAuthentication ->
-			clientAuthentication
-				.authenticationConverter(authenticationConverter)   <1>
-				.authenticationConverters(authenticationConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer)   <4>
-				.authenticationSuccessHandler(authenticationSuccessHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.clientAuthentication(clientAuthentication ->
+					clientAuthentication
+						.authenticationConverter(authenticationConverter)	<1>
+						.authenticationConverters(authenticationConvertersConsumer)	<2>
+						.authenticationProvider(authenticationProvider)	<3>
+						.authenticationProviders(authenticationProvidersConsumer)	<4>
+						.authenticationSuccessHandler(authenticationSuccessHandler)	<5>
+						.errorResponseHandler(errorResponseHandler)	<6>
+				)
 		);
 
 	return http.build();
@@ -288,13 +294,16 @@ The following example shows how to configure `JwtClientAssertionAuthenticationPr
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
 
-	authorizationServerConfigurer
-		.clientAuthentication(clientAuthentication ->
-			clientAuthentication
-				.authenticationProviders(configureJwtClientAssertionValidator())
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.clientAuthentication(clientAuthentication ->
+					clientAuthentication
+						.authenticationProviders(configureJwtClientAssertionValidator())
+				)
 		);
 
 	return http.build();
@@ -339,14 +348,17 @@ If you need to verify another attribute of the client `X509Certificate`, for exa
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-			new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
 
-	authorizationServerConfigurer
-			.clientAuthentication(clientAuthentication ->
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.clientAuthentication(clientAuthentication ->
 					clientAuthentication
-							.authenticationProviders(configureX509ClientCertificateVerifier())
-			);
+						.authenticationProviders(configureX509ClientCertificateVerifier())
+				)
+		);
 
 	return http.build();
 }

+ 33 - 25
docs/modules/ROOT/pages/core-model-components.adoc

@@ -123,13 +123,15 @@ Alternatively, you can configure the `RegisteredClientRepository` through the xr
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
 
-	authorizationServerConfigurer
-		.registeredClientRepository(registeredClientRepository);
-
-	...
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.registeredClientRepository(registeredClientRepository)
+		)
+	    ...
 
 	return http.build();
 }
@@ -218,13 +220,15 @@ Alternatively, you can configure the `OAuth2AuthorizationService` through the xr
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
 
-	authorizationServerConfigurer
-		.authorizationService(authorizationService);
-
-	...
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.authorizationService(authorizationService)
+		)
+	    ...
 
 	return http.build();
 }
@@ -290,13 +294,15 @@ Alternatively, you can configure the `OAuth2AuthorizationConsentService` through
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
 
-	authorizationServerConfigurer
-		.authorizationConsentService(authorizationConsentService);
-
-	...
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.authorizationConsentService(authorizationConsentService)
+		)
+	    ...
 
 	return http.build();
 }
@@ -401,13 +407,15 @@ Alternatively, you can configure the `OAuth2TokenGenerator` through the xref:con
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.tokenGenerator(tokenGenerator);
-
-	...
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.tokenGenerator(tokenGenerator)
+		)
+	    ...
 
 	return http.build();
 }

+ 3 - 4
docs/modules/ROOT/pages/guides/how-to-userinfo.adoc

@@ -31,7 +31,7 @@ TIP: Click on the "Expand folded text" icon in the code sample above to display
 This configuration provides the following:
 
 <1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
-<2> Resource server support that allows User Info requests to be authenticated with access tokens.
+<2> Enabling OpenID Connect 1.0 will autoconfigure resource server support that allows User Info requests to be authenticated with access tokens.
 <3> An instance of `JwtDecoder` used to validate access tokens.
 
 [[customize-user-info]]
@@ -87,9 +87,8 @@ This configuration maps claims from the access token (which is a JWT when using
 
 <1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
 <2> A user info mapper that maps claims in a domain-specific way.
-<3> An example showing the configuration option for customizing the user info mapper.
-<4> Resource server support that allows User Info requests to be authenticated with access tokens.
-<5> An example showing how to apply the `OAuth2AuthorizationServerConfigurer` to the Spring Security configuration.
+<3> Enabling OpenID Connect 1.0 will autoconfigure resource server support that allows User Info requests to be authenticated with access tokens.
+<4> An example showing the configuration option for customizing the user info mapper.
 
 The user info mapper is not limited to mapping claims from a JWT, but this is a simple example that demonstrates the customization option.
 Similar to the xref:guides/how-to-userinfo.adoc#customize-id-token[example shown earlier] where we customize claims of the ID token, you can customize claims of the access token itself ahead of time, as in the following example:

+ 209 - 209
docs/modules/ROOT/pages/protocol-endpoints.adoc

@@ -14,19 +14,22 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.authorizationEndpoint(authorizationEndpoint ->
-			authorizationEndpoint
-				.authorizationRequestConverter(authorizationRequestConverter)   <1>
-				.authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer)   <4>
-				.authorizationResponseHandler(authorizationResponseHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
-				.consentPage("/oauth2/v1/authorize")    <7>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.authorizationEndpoint(authorizationEndpoint ->
+					authorizationEndpoint
+        				.authorizationRequestConverter(authorizationRequestConverter)   <1>
+                        .authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .authorizationResponseHandler(authorizationResponseHandler) <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+                        .consentPage("/oauth2/v1/authorize")    <7>
+				)
 		);
 
 	return http.build();
@@ -74,13 +77,16 @@ The following example shows how to configure `OAuth2AuthorizationCodeRequestAuth
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.authorizationEndpoint(authorizationEndpoint ->
-			authorizationEndpoint
-				.authenticationProviders(configureAuthenticationValidator())
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.authorizationEndpoint(authorizationEndpoint ->
+					authorizationEndpoint
+                        .authenticationProviders(configureAuthenticationValidator())
+				)
 		);
 
 	return http.build();
@@ -133,19 +139,22 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
-			deviceAuthorizationEndpoint
-				.deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) <1>
-				.deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer) <4>
-				.deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
-				.verificationUri("/oauth2/v1/device_verification") <7>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
+                    deviceAuthorizationEndpoint
+                        .deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter)   <1>
+                        .deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+                        .verificationUri("/oauth2/v1/device_verification")  <7>
+				)
 		);
 
 	return http.build();
@@ -182,19 +191,22 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.deviceVerificationEndpoint(deviceVerificationEndpoint ->
-			deviceVerificationEndpoint
-				.deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
-				.deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer) <4>
-				.deviceVerificationResponseHandler(deviceVerificationResponseHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
-				.consentPage("/oauth2/v1/consent") <7>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.deviceVerificationEndpoint(deviceVerificationEndpoint ->
+                    deviceVerificationEndpoint
+                        .deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
+                        .deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer)   <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .deviceVerificationResponseHandler(deviceVerificationResponseHandler)   <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+                        .consentPage("/oauth2/v1/consent")  <7>
+				)
 		);
 
 	return http.build();
@@ -230,18 +242,21 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.tokenEndpoint(tokenEndpoint ->
-			tokenEndpoint
-				.accessTokenRequestConverter(accessTokenRequestConverter)   <1>
-				.accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer)   <4>
-				.accessTokenResponseHandler(accessTokenResponseHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.tokenEndpoint(tokenEndpoint ->
+                    tokenEndpoint
+                        .accessTokenRequestConverter(accessTokenRequestConverter)   <1>
+                        .accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .accessTokenResponseHandler(accessTokenResponseHandler) <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+				)
 		);
 
 	return http.build();
@@ -288,13 +303,16 @@ The following example shows how to configure `OAuth2ClientCredentialsAuthenticat
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.tokenEndpoint(tokenEndpoint ->
-			tokenEndpoint
-				.authenticationProviders(configureAuthenticationValidator())
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.tokenEndpoint(tokenEndpoint ->
+                    tokenEndpoint
+                        .authenticationProviders(configureAuthenticationValidator())
+				)
 		);
 
 	return http.build();
@@ -344,18 +362,21 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
-			tokenIntrospectionEndpoint
-				.introspectionRequestConverter(introspectionRequestConverter)   <1>
-				.introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer)   <4>
-				.introspectionResponseHandler(introspectionResponseHandler) <5>
-				.errorResponseHandler(errorResponseHandler) <6>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
+                    tokenIntrospectionEndpoint
+                        .introspectionRequestConverter(introspectionRequestConverter)   <1>
+                        .introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .introspectionResponseHandler(introspectionResponseHandler) <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+				)
 		);
 
 	return http.build();
@@ -391,18 +412,21 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.tokenRevocationEndpoint(tokenRevocationEndpoint ->
-			tokenRevocationEndpoint
-				.revocationRequestConverter(revocationRequestConverter) <1>
-				.revocationRequestConverters(revocationRequestConvertersConsumer)   <2>
-				.authenticationProvider(authenticationProvider) <3>
-				.authenticationProviders(authenticationProvidersConsumer)   <4>
-				.revocationResponseHandler(revocationResponseHandler)   <5>
-				.errorResponseHandler(errorResponseHandler) <6>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.tokenRevocationEndpoint(tokenRevocationEndpoint ->
+                    tokenRevocationEndpoint
+                        .revocationRequestConverter(revocationRequestConverter) <1>
+                        .revocationRequestConverters(revocationRequestConvertersConsumer)   <2>
+                        .authenticationProvider(authenticationProvider) <3>
+                        .authenticationProviders(authenticationProvidersConsumer)   <4>
+                        .revocationResponseHandler(revocationResponseHandler)   <5>
+                        .errorResponseHandler(errorResponseHandler) <6>
+				)
 		);
 
 	return http.build();
@@ -438,13 +462,17 @@ It defines an extension point that lets you customize the https://datatracker.ie
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
-			authorizationServerMetadataEndpoint
-				.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer));   <1>
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+				.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
+                    authorizationServerMetadataEndpoint
+                        .authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer)   <1>
+				)
+		);
 
 	return http.build();
 }
@@ -478,16 +506,19 @@ It defines an extension point that lets you customize the https://openid.net/spe
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.oidc(oidc ->
-			oidc
-				.providerConfigurationEndpoint(providerConfigurationEndpoint ->
-					providerConfigurationEndpoint
-						.providerConfigurationCustomizer(providerConfigurationCustomizer)   <1>
-				)
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+                .oidc(oidc ->
+                    oidc
+                        .providerConfigurationEndpoint(providerConfigurationEndpoint ->
+                            providerConfigurationEndpoint
+                                .providerConfigurationCustomizer(providerConfigurationCustomizer)   <1>
+                        )
+                )
 		);
 
 	return http.build();
@@ -511,21 +542,24 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.oidc(oidc ->
-			oidc
-				.logoutEndpoint(logoutEndpoint ->
-					logoutEndpoint
-						.logoutRequestConverter(logoutRequestConverter) <1>
-						.logoutRequestConverters(logoutRequestConvertersConsumer)   <2>
-						.authenticationProvider(authenticationProvider) <3>
-						.authenticationProviders(authenticationProvidersConsumer)   <4>
-						.logoutResponseHandler(logoutResponseHandler)   <5>
-						.errorResponseHandler(errorResponseHandler) <6>
-				)
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+                .oidc(oidc ->
+                    oidc
+                        .logoutEndpoint(logoutEndpoint ->
+                            logoutEndpoint
+                                .logoutRequestConverter(logoutRequestConverter) <1>
+                                .logoutRequestConverters(logoutRequestConvertersConsumer)   <2>
+                                .authenticationProvider(authenticationProvider) <3>
+                                .authenticationProviders(authenticationProvidersConsumer)   <4>
+                                .logoutResponseHandler(logoutResponseHandler)   <5>
+                                .errorResponseHandler(errorResponseHandler) <6>
+                        )
+                )
 		);
 
 	return http.build();
@@ -576,14 +610,19 @@ The following example shows how to configure `OidcLogoutAuthenticationProvider`
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-			new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.oidc(oidc ->
-			oidc
-				.logoutEndpoint(logoutEndpoint ->
-					logoutEndpoint.authenticationProviders(configureAuthenticationValidator()))
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+                .oidc(oidc ->
+                    oidc
+                        .logoutEndpoint(logoutEndpoint ->
+                            logoutEndpoint
+                                .authenticationProviders(configureAuthenticationValidator())
+                        )
+                )
 		);
 
 	return http.build();
@@ -626,22 +665,25 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.oidc(oidc ->
-			oidc
-				.userInfoEndpoint(userInfoEndpoint ->
-					userInfoEndpoint
-						.userInfoRequestConverter(userInfoRequestConverter) <1>
-						.userInfoRequestConverters(userInfoRequestConvertersConsumer) <2>
-						.authenticationProvider(authenticationProvider) <3>
-						.authenticationProviders(authenticationProvidersConsumer) <4>
-						.userInfoResponseHandler(userInfoResponseHandler) <5>
-						.errorResponseHandler(errorResponseHandler) <6>
-						.userInfoMapper(userInfoMapper) <7>
-				)
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+                .oidc(oidc ->
+                    oidc
+                        .userInfoEndpoint(userInfoEndpoint ->
+                            userInfoEndpoint
+                                .userInfoRequestConverter(userInfoRequestConverter) <1>
+                                .userInfoRequestConverters(userInfoRequestConvertersConsumer)   <2>
+                                .authenticationProvider(authenticationProvider) <3>
+                                .authenticationProviders(authenticationProvidersConsumer)   <4>
+                                .userInfoResponseHandler(userInfoResponseHandler)   <5>
+                                .errorResponseHandler(errorResponseHandler) <6>
+                                .userInfoMapper(userInfoMapper) <7>
+                        )
+                )
 		);
 
 	return http.build();
@@ -669,31 +711,9 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
 You can customize the ID Token by providing an xref:core-model-components.adoc#oauth2-token-customizer[`OAuth2TokenCustomizer<JwtEncodingContext>`] `@Bean`.
 
 The OpenID Connect 1.0 UserInfo endpoint is an OAuth2 protected resource, which *REQUIRES* an access token to be sent as a bearer token in the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo request].
-The following example shows how to enable the OAuth2 resource server configuration:
-
-[source,java]
-----
-@Bean
-public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	...
-
-	http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
-
-	return http.build();
-}
-
-@Bean
-public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
-	return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
-}
-----
 
 [NOTE]
-A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
+OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
 
 [TIP]
 The guide xref:guides/how-to-userinfo.adoc[How-to: Customize the OpenID Connect 1.0 UserInfo response] contains examples of customizing the UserInfo endpoint.
@@ -711,21 +731,24 @@ It defines extension points that let you customize the pre-processing, main proc
 @Bean
 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	authorizationServerConfigurer
-		.oidc(oidc ->
-			oidc
-				.clientRegistrationEndpoint(clientRegistrationEndpoint ->
-					clientRegistrationEndpoint
-						.clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
-						.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) <2>
-						.authenticationProvider(authenticationProvider) <3>
-						.authenticationProviders(authenticationProvidersConsumer) <4>
-						.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
-						.errorResponseHandler(errorResponseHandler) <6>
-				)
+			OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+	http
+		.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+		.with(authorizationServerConfigurer, (authorizationServer) ->
+			authorizationServer
+                .oidc(oidc ->
+                    oidc
+                        .clientRegistrationEndpoint(clientRegistrationEndpoint ->
+                            clientRegistrationEndpoint
+                                .clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
+                                .clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers)  <2>
+                                .authenticationProvider(authenticationProvider) <3>
+                                .authenticationProviders(authenticationProvidersConsumer)   <4>
+                                .clientRegistrationResponseHandler(clientRegistrationResponseHandler)   <5>
+                                .errorResponseHandler(errorResponseHandler) <6>
+                        )
+                )
 		);
 
 	return http.build();
@@ -756,34 +779,11 @@ The OpenID Connect 1.0 Client Registration endpoint is disabled by default becau
 
 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.
 
+[NOTE]
+OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.
+
 [IMPORTANT]
 The access token in a Client Registration request *REQUIRES* the OAuth2 scope `client.create`.
 
 [IMPORTANT]
 The access token in a Client Read request *REQUIRES* the OAuth2 scope `client.read`.
-
-The following example shows how to enable the OAuth2 resource server configuration:
-
-[source,java]
-----
-@Bean
-public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-		new OAuth2AuthorizationServerConfigurer();
-	http.apply(authorizationServerConfigurer);
-
-	...
-
-	http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
-
-	return http.build();
-}
-
-@Bean
-public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
-	return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
-}
-----
-
-[NOTE]
-A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.

+ 14 - 20
docs/src/main/java/sample/extgrant/SecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,6 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Acce
 import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
 import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 
 @Configuration
 @EnableWebSecurity
@@ -53,29 +52,24 @@ public class SecurityConfig {
 			OAuth2TokenGenerator<?> tokenGenerator) throws Exception {
 
 		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-				new OAuth2AuthorizationServerConfigurer();
-
-		authorizationServerConfigurer
-			.tokenEndpoint(tokenEndpoint ->
-				tokenEndpoint
-					.accessTokenRequestConverter( // <1>
-						new CustomCodeGrantAuthenticationConverter())
-					.authenticationProvider( // <2>
-						new CustomCodeGrantAuthenticationProvider(
-							authorizationService, tokenGenerator)));
-
-		// @fold:on
-		RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
 
 		http
-			.securityMatcher(endpointsMatcher)
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.tokenEndpoint(tokenEndpoint ->
+						tokenEndpoint
+							.accessTokenRequestConverter(	// <1>
+								new CustomCodeGrantAuthenticationConverter())
+							.authenticationProvider(	// <2>
+								new CustomCodeGrantAuthenticationProvider(
+									authorizationService, tokenGenerator)))
+			)
 			.authorizeHttpRequests(authorize ->
 				authorize
 					.anyRequest().authenticated()
-			)
-			.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
-			.apply(authorizationServerConfigurer);
-		// @fold:off
+			);
 
 		return http.build();
 	}

+ 10 - 8
docs/src/main/java/sample/gettingstarted/SecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -61,11 +61,16 @@ public class SecurityConfig {
 	@Order(1)
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
 			throws Exception {
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-			.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
 		// @formatter:off
 		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+			)
 			// Redirect to the login page when not authenticated from the
 			// authorization endpoint
 			.exceptionHandling((exceptions) -> exceptions
@@ -73,10 +78,7 @@ public class SecurityConfig {
 					new LoginUrlAuthenticationEntryPoint("/login"),
 					new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 				)
-			)
-			// Accept access tokens for User Info and/or Client Registration
-			.oauth2ResourceServer((resourceServer) -> resourceServer
-				.jwt(Customizer.withDefaults()));
+			);
 		// @formatter:on
 
 		return http.build();

+ 11 - 9
docs/src/main/java/sample/pkce/SecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
 import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
 import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@@ -40,11 +39,16 @@ public class SecurityConfig {
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
 			throws Exception {
 		// @fold:on
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-			.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
 		// @formatter:off
 		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+			)
 			// Redirect to the login page when not authenticated from the
 			// authorization endpoint
 			.exceptionHandling((exceptions) -> exceptions
@@ -52,9 +56,7 @@ public class SecurityConfig {
 					new LoginUrlAuthenticationEntryPoint("/login"),
 					new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 				)
-			)
-			// Accept access tokens for User Info and/or Client Registration
-			.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
+			);
 		// @formatter:on
 
 		// @fold:off
@@ -92,4 +94,4 @@ public class SecurityConfig {
 		return source;
 	}
 
-}
+}

+ 17 - 11
docs/src/main/java/sample/registration/SecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@ package sample.registration;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
 import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
 import org.springframework.security.web.SecurityFilterChain;
 
@@ -32,14 +30,22 @@ public class SecurityConfig {
 
 	@Bean
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-				.oidc(oidc -> oidc.clientRegistrationEndpoint(clientRegistrationEndpoint -> {	// <1>
-					clientRegistrationEndpoint
-							.authenticationProviders(configureCustomClientMetadataConverters());	// <2>
-				}));
-		http.oauth2ResourceServer(oauth2ResourceServer ->
-				oauth2ResourceServer.jwt(Customizer.withDefaults()));
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
+		// @formatter:off
+		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc((oidc) ->
+						oidc.clientRegistrationEndpoint((clientRegistrationEndpoint) ->	// <1>
+							clientRegistrationEndpoint
+								.authenticationProviders(configureCustomClientMetadataConverters())	// <2>
+						)
+					)
+			);
+		// @formatter:on
 
 		return http.build();
 	}

+ 10 - 8
docs/src/main/java/sample/sociallogin/SecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
 import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
 import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@@ -36,11 +35,16 @@ public class SecurityConfig {
 	@Order(1)
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
 			throws Exception {
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-			.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
 		// @formatter:off
 		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+			)
 			// Redirect to the OAuth 2.0 Login endpoint when not authenticated
 			// from the authorization endpoint
 			.exceptionHandling((exceptions) -> exceptions
@@ -48,9 +52,7 @@ public class SecurityConfig {
 					new LoginUrlAuthenticationEntryPoint("/oauth2/authorization/my-client"),
 					new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 				)
-			)
-			// Accept access tokens for User Info and/or Client Registration
-			.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
+			);
 		// @formatter:on
 
 		return http.build();

+ 9 - 5
docs/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -60,12 +60,16 @@ public class EnableUserInfoSecurityConfig {
 	@Bean // <1>
 	@Order(1)
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-			.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
 		// @formatter:off
 		http
-			.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())) // <2>
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc(Customizer.withDefaults())	// <2>
+			)
 			.exceptionHandling((exceptions) -> exceptions
 				.defaultAuthenticationEntryPointFor(
 					new LoginUrlAuthenticationEntryPoint("/login"),

+ 16 - 22
docs/src/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,50 +57,44 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
 import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 
 @Configuration(proxyBeanMethods = false)
 @EnableWebSecurity
 public class JwtUserInfoMapperSecurityConfig {
 
-	@Bean // <1>
+	@Bean	// <1>
 	@Order(1)
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-				new OAuth2AuthorizationServerConfigurer();
-		RequestMatcher endpointsMatcher = authorizationServerConfigurer
-				.getEndpointsMatcher();
-
-		Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> { // <2>
+		Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> {	// <2>
 			OidcUserInfoAuthenticationToken authentication = context.getAuthentication();
 			JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();
 
 			return new OidcUserInfo(principal.getToken().getClaims());
 		};
 
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+
 		// @formatter:off
-		authorizationServerConfigurer
-			.oidc((oidc) -> oidc
-				.userInfoEndpoint((userInfo) -> userInfo
-					.userInfoMapper(userInfoMapper) // <3>
-				)
-			);
 		http
-			.securityMatcher(endpointsMatcher)
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.oidc((oidc) -> oidc	// <3>
+						.userInfoEndpoint((userInfo) -> userInfo
+							.userInfoMapper(userInfoMapper)	// <4>
+						)
+					)
+			)
 			.authorizeHttpRequests((authorize) -> authorize
 				.anyRequest().authenticated()
 			)
-			.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
-			.oauth2ResourceServer(resourceServer -> resourceServer
-				.jwt(Customizer.withDefaults()) // <4>
-			)
 			.exceptionHandling((exceptions) -> exceptions
 				.defaultAuthenticationEntryPointFor(
 					new LoginUrlAuthenticationEntryPoint("/login"),
 					new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 				)
-			)
-			.apply(authorizationServerConfigurer); // <5>
+			);
 		// @formatter:on
 
 		return http.build();

+ 8 - 7
docs/src/test/java/sample/jpa/JpaTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -196,20 +196,21 @@ public class JpaTests {
 		@Bean
 		@Order(Ordered.HIGHEST_PRECEDENCE)
 		public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-			http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-					.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 
 			// @formatter:off
 			http
+				.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+				.with(authorizationServerConfigurer, (authorizationServer) ->
+					authorizationServer
+						.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+				)
 				.exceptionHandling((exceptions) -> exceptions
 					.defaultAuthenticationEntryPointFor(
 						new LoginUrlAuthenticationEntryPoint("/login"),
 						new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 					)
-				)
-				.oauth2ResourceServer((resourceServer) -> resourceServer
-					.jwt(Customizer.withDefaults())
 				);
 			// @formatter:on
 			return http.build();

+ 28 - 13
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,13 +30,14 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
 import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
 import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 
 /**
  * {@link Configuration} for OAuth 2.0 Authorization Server support.
@@ -51,26 +52,40 @@ public class OAuth2AuthorizationServerConfiguration {
 	@Bean
 	@Order(Ordered.HIGHEST_PRECEDENCE)
 	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-		applyDefaultSecurity(http);
+		// @formatter:off
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
+		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, Customizer.withDefaults())
+			.authorizeHttpRequests((authorize) ->
+				authorize.anyRequest().authenticated()
+			);
+		// @formatter:on
 		return http.build();
 	}
 
-	// @formatter:off
+	/**
+	 * @param http the {@link HttpSecurity}
+	 * @throws Exception if {@link OAuth2AuthorizationServerConfigurer} could not be
+	 * applied
+	 * @deprecated For removal in 2.0. Use
+	 * {@link HttpSecurity#with(SecurityConfigurerAdapter, Customizer)} and pass in
+	 * {@link OAuth2AuthorizationServerConfigurer#authorizationServer()}.
+	 */
+	@Deprecated(since = "1.4", forRemoval = true)
 	public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
+		// @formatter:off
 		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-				new OAuth2AuthorizationServerConfigurer();
-		RequestMatcher endpointsMatcher = authorizationServerConfigurer
-				.getEndpointsMatcher();
-
+				OAuth2AuthorizationServerConfigurer.authorizationServer();
 		http
-			.securityMatcher(endpointsMatcher)
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, Customizer.withDefaults())
 			.authorizeHttpRequests((authorize) ->
 				authorize.anyRequest().authenticated()
-			)
-			.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-			.apply(authorizationServerConfigurer);
+			);
+		// @formatter:on
 	}
-	// @formatter:on
 
 	public static JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
 		Set<JWSAlgorithm> jwsAlgs = new HashSet<>();

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

@@ -87,6 +87,17 @@ public final class OAuth2AuthorizationServerConfigurer
 
 	private RequestMatcher endpointsMatcher;
 
+	/**
+	 * Returns a new instance of {@link OAuth2AuthorizationServerConfigurer} for
+	 * configuring.
+	 * @return a new instance of {@link OAuth2AuthorizationServerConfigurer} for
+	 * configuring
+	 * @since 1.4
+	 */
+	public static OAuth2AuthorizationServerConfigurer authorizationServer() {
+		return new OAuth2AuthorizationServerConfigurer();
+	}
+
 	/**
 	 * Sets the repository of registered clients.
 	 * @param registeredClientRepository the repository of registered clients
@@ -277,7 +288,7 @@ public final class OAuth2AuthorizationServerConfigurer
 	}
 
 	@Override
-	public void init(HttpSecurity httpSecurity) {
+	public void init(HttpSecurity httpSecurity) throws Exception {
 		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils
 			.getAuthorizationServerSettings(httpSecurity);
 		validateAuthorizationServerSettings(authorizationServerSettings);
@@ -339,6 +350,20 @@ public final class OAuth2AuthorizationServerConfigurer
 							getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class),
 							getRequestMatcher(OAuth2DeviceAuthorizationEndpointConfigurer.class)));
 		}
+
+		httpSecurity.csrf((csrf) -> csrf.ignoringRequestMatchers(this.endpointsMatcher));
+
+		OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class);
+		if (oidcConfigurer != null) {
+			if (oidcConfigurer.getConfigurer(OidcUserInfoEndpointConfigurer.class) != null
+					|| oidcConfigurer.getConfigurer(OidcClientRegistrationEndpointConfigurer.class) != null) {
+				httpSecurity
+					// Accept access tokens for User Info and/or Client Registration
+					.oauth2ResourceServer(
+							(oauth2ResourceServer) -> oauth2ResourceServer.jwt(Customizer.withDefaults()));
+
+			}
+		}
 	}
 
 	@Override

+ 35 - 44
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java

@@ -61,6 +61,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.core.Authentication;
@@ -124,7 +125,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
 import org.springframework.security.web.context.SecurityContextRepository;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.LinkedMultiValueMap;
@@ -1149,18 +1149,15 @@ public class OAuth2AuthorizationCodeGrantTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, Customizer.withDefaults())
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
 					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
 					.securityContext((securityContext) ->
-							securityContext.securityContextRepository(securityContextRepository))
-					.apply(authorizationServerConfigurer);
+							securityContext.securityContextRepository(securityContextRepository));
 			return http.build();
 		}
 		// @formatter:on
@@ -1212,19 +1209,17 @@ public class OAuth2AuthorizationCodeGrantTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.authorizationEndpoint((authorizationEndpoint) ->
-							authorizationEndpoint.consentPage(consentPage));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.authorizationEndpoint((authorizationEndpoint) ->
+											authorizationEndpoint.consentPage(consentPage))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -1242,19 +1237,17 @@ public class OAuth2AuthorizationCodeGrantTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.authorizationEndpoint((authorizationEndpoint) ->
-							authorizationEndpoint.authenticationProviders(configureAuthenticationProviders()));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.authorizationEndpoint((authorizationEndpoint) ->
+											authorizationEndpoint.authenticationProviders(configureAuthenticationProviders()))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -1331,25 +1324,23 @@ public class OAuth2AuthorizationCodeGrantTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.authorizationEndpoint((authorizationEndpoint) ->
-							authorizationEndpoint
-									.authorizationRequestConverter(authorizationRequestConverter)
-									.authorizationRequestConverters(authorizationRequestConvertersConsumer)
-									.authenticationProvider(authorizationRequestAuthenticationProvider)
-									.authenticationProviders(authorizationRequestAuthenticationProvidersConsumer)
-									.authorizationResponseHandler(authorizationResponseHandler)
-									.errorResponseHandler(authorizationErrorResponseHandler));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.authorizationEndpoint((authorizationEndpoint) ->
+											authorizationEndpoint
+													.authorizationRequestConverter(authorizationRequestConverter)
+													.authorizationRequestConverters(authorizationRequestConvertersConsumer)
+													.authenticationProvider(authorizationRequestAuthenticationProvider)
+													.authenticationProviders(authorizationRequestAuthenticationProvidersConsumer)
+													.authorizationResponseHandler(authorizationResponseHandler)
+													.errorResponseHandler(authorizationErrorResponseHandler))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 9 - 15
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerMetadataTests.java

@@ -49,7 +49,6 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
 import org.springframework.security.oauth2.server.authorization.test.SpringTestContext;
 import org.springframework.security.oauth2.server.authorization.test.SpringTestContextExtension;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 
 import static org.hamcrest.CoreMatchers.hasItems;
@@ -194,23 +193,18 @@ public class OAuth2AuthorizationServerMetadataTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			http.apply(authorizationServerConfigurer);
-
-			authorizationServerConfigurer
-					.authorizationServerMetadataEndpoint((authorizationServerMetadataEndpoint) ->
-							authorizationServerMetadataEndpoint
-									.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer()));
-
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.authorizationServerMetadataEndpoint((authorizationServerMetadataEndpoint) ->
+											authorizationServerMetadataEndpoint
+													.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer()))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
-
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 28 - 33
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ClientCredentialsGrantTests.java

@@ -104,7 +104,6 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 
@@ -541,25 +540,23 @@ public class OAuth2ClientCredentialsGrantTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.tokenEndpoint((tokenEndpoint) ->
-							tokenEndpoint
-									.accessTokenRequestConverter(authenticationConverter)
-									.accessTokenRequestConverters(authenticationConvertersConsumer)
-									.authenticationProvider(authenticationProvider)
-									.authenticationProviders(authenticationProvidersConsumer)
-									.accessTokenResponseHandler(authenticationSuccessHandler)
-									.errorResponseHandler(authenticationFailureHandler));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.tokenEndpoint((tokenEndpoint) ->
+											tokenEndpoint
+													.accessTokenRequestConverter(authenticationConverter)
+													.accessTokenRequestConverters(authenticationConvertersConsumer)
+													.authenticationProvider(authenticationProvider)
+													.authenticationProviders(authenticationProvidersConsumer)
+													.accessTokenResponseHandler(authenticationSuccessHandler)
+													.errorResponseHandler(authenticationFailureHandler))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -587,25 +584,23 @@ public class OAuth2ClientCredentialsGrantTests {
 			authenticationSuccessHandler = spy(authenticationSuccessHandler());
 
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.clientAuthentication((clientAuthentication) ->
-							clientAuthentication
-									.authenticationConverter(authenticationConverter)
-									.authenticationConverters(authenticationConvertersConsumer)
-									.authenticationProvider(authenticationProvider)
-									.authenticationProviders(authenticationProvidersConsumer)
-									.authenticationSuccessHandler(authenticationSuccessHandler)
-									.errorResponseHandler(authenticationFailureHandler));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.clientAuthentication((clientAuthentication) ->
+											clientAuthentication
+													.authenticationConverter(authenticationConverter)
+													.authenticationConverters(authenticationConvertersConsumer)
+													.authenticationProvider(authenticationProvider)
+													.authenticationProviders(authenticationProvidersConsumer)
+													.authenticationSuccessHandler(authenticationSuccessHandler)
+													.errorResponseHandler(authenticationFailureHandler))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 12 - 16
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2RefreshTokenGrantTests.java

@@ -91,7 +91,6 @@ import org.springframework.security.oauth2.server.authorization.token.JwtEncodin
 import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.Assert;
@@ -373,24 +372,21 @@ public class OAuth2RefreshTokenGrantTests {
 				HttpSecurity http, RegisteredClientRepository registeredClientRepository) throws Exception {
 
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.clientAuthentication((clientAuthentication) ->
-							clientAuthentication
-									.authenticationConverter(
-											new PublicClientRefreshTokenAuthenticationConverter())
-									.authenticationProvider(
-											new PublicClientRefreshTokenAuthenticationProvider(registeredClientRepository))
-					);
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.clientAuthentication((clientAuthentication) ->
+											clientAuthentication
+													.authenticationConverter(
+															new PublicClientRefreshTokenAuthenticationConverter())
+													.authenticationProvider(
+															new PublicClientRefreshTokenAuthenticationProvider(registeredClientRepository)))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 14 - 17
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenIntrospectionTests.java

@@ -98,7 +98,6 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.LinkedMultiValueMap;
@@ -576,25 +575,23 @@ public class OAuth2TokenIntrospectionTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.tokenIntrospectionEndpoint((tokenIntrospectionEndpoint) ->
-							tokenIntrospectionEndpoint
-									.introspectionRequestConverter(authenticationConverter)
-									.introspectionRequestConverters(authenticationConvertersConsumer)
-									.authenticationProvider(authenticationProvider)
-									.authenticationProviders(authenticationProvidersConsumer)
-									.introspectionResponseHandler(authenticationSuccessHandler)
-									.errorResponseHandler(authenticationFailureHandler));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.tokenIntrospectionEndpoint((tokenIntrospectionEndpoint) ->
+											tokenIntrospectionEndpoint
+													.introspectionRequestConverter(authenticationConverter)
+													.introspectionRequestConverters(authenticationConvertersConsumer)
+													.authenticationProvider(authenticationProvider)
+													.authenticationProviders(authenticationProvidersConsumer)
+													.introspectionResponseHandler(authenticationSuccessHandler)
+													.errorResponseHandler(authenticationFailureHandler))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 14 - 17
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenRevocationTests.java

@@ -77,7 +77,6 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
@@ -376,25 +375,23 @@ public class OAuth2TokenRevocationTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.tokenRevocationEndpoint((tokenRevocationEndpoint) ->
-							tokenRevocationEndpoint
-									.revocationRequestConverter(authenticationConverter)
-									.revocationRequestConverters(authenticationConvertersConsumer)
-									.authenticationProvider(authenticationProvider)
-									.authenticationProviders(authenticationProvidersConsumer)
-									.revocationResponseHandler(authenticationSuccessHandler)
-									.errorResponseHandler(authenticationFailureHandler));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.tokenRevocationEndpoint((tokenRevocationEndpoint) ->
+											tokenRevocationEndpoint
+													.revocationRequestConverter(authenticationConverter)
+													.revocationRequestConverters(authenticationConvertersConsumer)
+													.authenticationProvider(authenticationProvider)
+													.authenticationProviders(authenticationProvidersConsumer)
+													.revocationResponseHandler(authenticationSuccessHandler)
+													.errorResponseHandler(authenticationFailureHandler))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

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

@@ -104,7 +104,6 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.CollectionUtils;
@@ -615,32 +614,27 @@ public class OidcClientRegistrationTests {
 		@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)
-						)
-				);
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc
+													.clientRegistrationEndpoint((clientRegistration) ->
+															clientRegistration
+																	.clientRegistrationRequestConverter(authenticationConverter)
+																	.clientRegistrationRequestConverters(authenticationConvertersConsumer)
+																	.authenticationProvider(authenticationProvider)
+																	.authenticationProviders(authenticationProvidersConsumer)
+																	.clientRegistrationResponseHandler(authenticationSuccessHandler)
+																	.errorResponseHandler(authenticationFailureHandler)
+													)
+									)
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.oauth2ResourceServer((resourceServer) ->
-						resourceServer.jwt(Customizer.withDefaults())
-					)
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -656,27 +650,22 @@ public class OidcClientRegistrationTests {
 		@Override
 		public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-				.oidc((oidc) ->
-					oidc
-						.clientRegistrationEndpoint((clientRegistration) ->
-							clientRegistration
-								.authenticationProviders(configureClientRegistrationConverters())
-						)
-				);
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc
+													.clientRegistrationEndpoint((clientRegistration) ->
+															clientRegistration
+																	.authenticationProviders(configureClientRegistrationConverters())
+													)
+									)
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.oauth2ResourceServer((resourceServer) ->
-							resourceServer.jwt(Customizer.withDefaults())
-					)
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -704,22 +693,19 @@ public class OidcClientRegistrationTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			authorizationServerConfigurer
-					.oidc((oidc) ->
-							oidc.clientRegistrationEndpoint(Customizer.withDefaults()));
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc
+													.clientRegistrationEndpoint(Customizer.withDefaults())
+									)
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-					.oauth2ResourceServer((resourceServer) ->
-							resourceServer.jwt(Customizer.withDefaults())
-					)
-					.apply(authorizationServerConfigurer);
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 44 - 26
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java

@@ -17,6 +17,10 @@ package org.springframework.security.oauth2.server.authorization.config.annotati
 
 import java.util.function.Consumer;
 
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.proc.SecurityContext;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 
@@ -30,7 +34,9 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
 import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
 import org.springframework.security.oauth2.core.oidc.OidcScopes;
+import org.springframework.security.oauth2.jose.TestJwks;
 import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
+import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimNames;
 import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
 import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -42,7 +48,6 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
 import org.springframework.security.oauth2.server.authorization.test.SpringTestContext;
 import org.springframework.security.oauth2.server.authorization.test.SpringTestContextExtension;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.ResultMatcher;
 
@@ -222,9 +227,16 @@ public class OidcProviderConfigurationTests {
 
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-			// Enable OpenID Connect 1.0
-			http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer
+				.authorizationServer();
+			// @formatter:off
+			http
+				.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+				.with(authorizationServerConfigurer, (authorizationServer) ->
+					authorizationServer
+						.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+				);
+			// @formatter:on
 			return http.build();
 		}
 
@@ -234,6 +246,16 @@ public class OidcProviderConfigurationTests {
 			return new InMemoryRegisteredClientRepository(registeredClient);
 		}
 
+		@Bean
+		JWKSource<SecurityContext> jwkSource() {
+			return new ImmutableJWKSet<>(new JWKSet(TestJwks.DEFAULT_RSA_JWK));
+		}
+
+		@Bean
+		JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
+			return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
+		}
+
 		@Bean
 		AuthorizationServerSettings authorizationServerSettings() {
 			return AuthorizationServerSettings.builder().issuer(ISSUER).build();
@@ -261,24 +283,19 @@ public class OidcProviderConfigurationTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			http.apply(authorizationServerConfigurer);
-
-			authorizationServerConfigurer
-					.oidc((oidc) ->
-							oidc.providerConfigurationEndpoint((providerConfigurationEndpoint) ->
-									providerConfigurationEndpoint
-											.providerConfigurationCustomizer(providerConfigurationCustomizer())));
-
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc.providerConfigurationEndpoint((providerConfigurationEndpoint) ->
+													providerConfigurationEndpoint
+															.providerConfigurationCustomizer(providerConfigurationCustomizer())))
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
-
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -298,14 +315,15 @@ public class OidcProviderConfigurationTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			http.apply(authorizationServerConfigurer);
-
-			authorizationServerConfigurer
-					.oidc((oidc) ->
-							oidc.clientRegistrationEndpoint(Customizer.withDefaults())
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
+			http
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc.clientRegistrationEndpoint(Customizer.withDefaults())
+									)
 					);
-
 			return http.build();
 		}
 		// @formatter:on

+ 26 - 31
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java

@@ -96,7 +96,6 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Toke
 import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
 import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.LinkedMultiValueMap;
@@ -599,9 +598,16 @@ public class OidcTests {
 
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-			// Enable OpenID Connect 1.0
-			http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
+			// @formatter:off
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
+			http
+				.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+				.with(authorizationServerConfigurer, (authorizationServer) ->
+					authorizationServer
+						.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+				);
+			// @formatter:on
 			return http.build();
 		}
 
@@ -696,23 +702,17 @@ public class OidcTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			http.apply(authorizationServerConfigurer);
-
-			// Enable OpenID Connect 1.0
-			authorizationServerConfigurer
-					.tokenGenerator(tokenGenerator())
-					.oidc(Customizer.withDefaults());
-
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.tokenGenerator(tokenGenerator())
+									.oidc(Customizer.withDefaults())
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
-
+					);
 			return http.build();
 		}
 		// @formatter:on
@@ -743,22 +743,17 @@ public class OidcTests {
 		@Bean
 		SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
 			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
-					new OAuth2AuthorizationServerConfigurer();
-			http.apply(authorizationServerConfigurer);
-
-			authorizationServerConfigurer
-					.tokenGenerator(tokenGenerator())
-					.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
-
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-					.securityMatcher(endpointsMatcher)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.tokenGenerator(tokenGenerator())
+									.oidc(Customizer.withDefaults())
+					)
 					.authorizeHttpRequests((authorize) ->
 							authorize.anyRequest().authenticated()
-					)
-					.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
-
+					);
 			return http.build();
 		}
 		// @formatter:on

+ 41 - 54
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcUserInfoTests.java

@@ -79,7 +79,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
 import org.springframework.security.web.context.SecurityContextRepository;
-import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.ResultMatcher;
@@ -405,33 +404,29 @@ public class OidcUserInfoTests {
 		@Bean
 		@Override
 		SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
 			// @formatter:off
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-				.securityMatcher(endpointsMatcher)
-				.authorizeHttpRequests((authorize) ->
-					authorize.anyRequest().authenticated()
-				)
-				.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-				.oauth2ResourceServer((resourceServer) ->
-					resourceServer.jwt(Customizer.withDefaults())
-				)
-				.apply(authorizationServerConfigurer)
-					.oidc((oidc) -> oidc
-						.userInfoEndpoint((userInfo) -> userInfo
-							.userInfoRequestConverter(authenticationConverter)
-							.userInfoRequestConverters(authenticationConvertersConsumer)
-							.authenticationProvider(authenticationProvider)
-							.authenticationProviders(authenticationProvidersConsumer)
-							.userInfoResponseHandler(authenticationSuccessHandler)
-							.errorResponseHandler(authenticationFailureHandler)
-							.userInfoMapper(userInfoMapper)
-						)
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc((oidc) ->
+											oidc
+													.userInfoEndpoint((userInfo) ->
+															userInfo
+																	.userInfoRequestConverter(authenticationConverter)
+																	.userInfoRequestConverters(authenticationConvertersConsumer)
+																	.authenticationProvider(authenticationProvider)
+																	.authenticationProviders(authenticationProvidersConsumer)
+																	.userInfoResponseHandler(authenticationSuccessHandler)
+																	.errorResponseHandler(authenticationFailureHandler)
+																	.userInfoMapper(userInfoMapper)))
+					)
+					.authorizeHttpRequests((authorize) ->
+							authorize.anyRequest().authenticated()
 					);
 			// @formatter:on
-
 			return http.build();
 		}
 
@@ -445,24 +440,20 @@ public class OidcUserInfoTests {
 		@Bean
 		@Override
 		SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
-			// Enable OpenID Connect 1.0
-			authorizationServerConfigurer.oidc(Customizer.withDefaults());
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
 			// @formatter:off
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-				.securityMatcher(endpointsMatcher)
-				.authorizeHttpRequests((authorize) ->
-					authorize.anyRequest().authenticated()
-				)
-				.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-				.oauth2ResourceServer((resourceServer) ->
-					resourceServer.jwt(Customizer.withDefaults())
-				)
-				.securityContext((securityContext) ->
-					securityContext.securityContextRepository(securityContextRepository))
-				.apply(authorizationServerConfigurer);
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc(Customizer.withDefaults())
+					)
+					.authorizeHttpRequests((authorize) ->
+							authorize.anyRequest().authenticated()
+					)
+					.securityContext((securityContext) ->
+							securityContext.securityContextRepository(securityContextRepository));
 			// @formatter:on
 
 			return http.build();
@@ -476,22 +467,18 @@ public class OidcUserInfoTests {
 
 		@Bean
 		SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
-			// Enable OpenID Connect 1.0
-			authorizationServerConfigurer.oidc(Customizer.withDefaults());
-			RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
-
 			// @formatter:off
+			OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
+					OAuth2AuthorizationServerConfigurer.authorizationServer();
 			http
-				.securityMatcher(endpointsMatcher)
-				.authorizeHttpRequests((authorize) ->
-					authorize.anyRequest().authenticated()
-				)
-				.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
-				.oauth2ResourceServer((resourceServer) ->
-					resourceServer.jwt(Customizer.withDefaults())
-				)
-				.apply(authorizationServerConfigurer);
+					.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+					.with(authorizationServerConfigurer, (authorizationServer) ->
+							authorizationServer
+									.oidc(Customizer.withDefaults())
+					)
+					.authorizeHttpRequests((authorize) ->
+							authorize.anyRequest().authenticated()
+					);
 			// @formatter:on
 
 			return http.build();

+ 27 - 22
samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

@@ -57,6 +57,8 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
 import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
 
+import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer;
+
 /**
  * @author Joe Grandja
  * @author Daniel Garnier-Moiroux
@@ -73,8 +75,6 @@ public class AuthorizationServerConfig {
 			HttpSecurity http, RegisteredClientRepository registeredClientRepository,
 			AuthorizationServerSettings authorizationServerSettings) throws Exception {
 
-		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-
 		/*
 		 * This sample demonstrates the use of a public client that does not
 		 * store credentials or authenticate with the authorization server.
@@ -97,34 +97,39 @@ public class AuthorizationServerConfig {
 		DeviceClientAuthenticationProvider deviceClientAuthenticationProvider =
 				new DeviceClientAuthenticationProvider(registeredClientRepository);
 
-		// @formatter:off
-		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
-			.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
-				deviceAuthorizationEndpoint.verificationUri("/activate")
-			)
-			.deviceVerificationEndpoint(deviceVerificationEndpoint ->
-				deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
-			)
-			.clientAuthentication(clientAuthentication ->
-				clientAuthentication
-					.authenticationConverter(deviceClientAuthenticationConverter)
-					.authenticationProvider(deviceClientAuthenticationProvider)
-			)
-			.authorizationEndpoint(authorizationEndpoint ->
-				authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
-			.oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0
-		// @formatter:on
+		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = authorizationServer();
 
 		// @formatter:off
 		http
+			.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
+			.with(authorizationServerConfigurer, (authorizationServer) ->
+				authorizationServer
+					.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
+						deviceAuthorizationEndpoint.verificationUri("/activate")
+					)
+					.deviceVerificationEndpoint(deviceVerificationEndpoint ->
+						deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
+					)
+					.clientAuthentication(clientAuthentication ->
+						clientAuthentication
+							.authenticationConverter(deviceClientAuthenticationConverter)
+							.authenticationProvider(deviceClientAuthenticationProvider)
+					)
+					.authorizationEndpoint(authorizationEndpoint ->
+						authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
+					.oidc(Customizer.withDefaults())	// Enable OpenID Connect 1.0
+			)
+			.authorizeHttpRequests((authorize) ->
+				authorize.anyRequest().authenticated()
+			)
+			// Redirect to the /login page when not authenticated from the authorization endpoint
+			// NOTE: DefaultSecurityConfig is configured with formLogin.loginPage("/login")
 			.exceptionHandling((exceptions) -> exceptions
 				.defaultAuthenticationEntryPointFor(
 					new LoginUrlAuthenticationEntryPoint("/login"),
 					new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
 				)
-			)
-			.oauth2ResourceServer(oauth2ResourceServer ->
-				oauth2ResourceServer.jwt(Customizer.withDefaults()));
+			);
 		// @formatter:on
 		return http.build();
 	}