diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java index 8a027fe3e2..0c4f15e02e 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java @@ -482,6 +482,27 @@ public final class OAuth2AuthorizationServerConfigurer }); } + OAuth2PushedAuthorizationRequestEndpointConfigurer pushedAuthorizationRequestEndpointConfigurer = getConfigurer( + OAuth2PushedAuthorizationRequestEndpointConfigurer.class); + if (pushedAuthorizationRequestEndpointConfigurer != null) { + OAuth2AuthorizationServerMetadataEndpointConfigurer authorizationServerMetadataEndpointConfigurer = getConfigurer( + OAuth2AuthorizationServerMetadataEndpointConfigurer.class); + + authorizationServerMetadataEndpointConfigurer.addDefaultAuthorizationServerMetadataCustomizer((builder) -> { + AuthorizationServerContext authorizationServerContext = AuthorizationServerContextHolder.getContext(); + String issuer = authorizationServerContext.getIssuer(); + AuthorizationServerSettings authorizationServerSettings = authorizationServerContext + .getAuthorizationServerSettings(); + + String pushedAuthorizationRequestEndpoint = UriComponentsBuilder.fromUriString(issuer) + .path(authorizationServerSettings.getPushedAuthorizationRequestEndpoint()) + .build() + .toUriString(); + + builder.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint); + }); + } + this.configurers.values().forEach((configurer) -> configurer.configure(httpSecurity)); AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java index d1d909d31b..5ecf6cc3ba 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java @@ -171,6 +171,28 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer { }); } + OAuth2PushedAuthorizationRequestEndpointConfigurer pushedAuthorizationRequestEndpointConfigurer = httpSecurity + .getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .getConfigurer(OAuth2PushedAuthorizationRequestEndpointConfigurer.class); + if (pushedAuthorizationRequestEndpointConfigurer != null) { + OidcProviderConfigurationEndpointConfigurer providerConfigurationEndpointConfigurer = getConfigurer( + OidcProviderConfigurationEndpointConfigurer.class); + + providerConfigurationEndpointConfigurer.addDefaultProviderConfigurationCustomizer((builder) -> { + AuthorizationServerContext authorizationServerContext = AuthorizationServerContextHolder.getContext(); + String issuer = authorizationServerContext.getIssuer(); + AuthorizationServerSettings authorizationServerSettings = authorizationServerContext + .getAuthorizationServerSettings(); + + String pushedAuthorizationRequestEndpoint = UriComponentsBuilder.fromUriString(issuer) + .path(authorizationServerSettings.getPushedAuthorizationRequestEndpoint()) + .build() + .toUriString(); + + builder.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint); + }); + } + this.configurers.values().forEach((configurer) -> configurer.configure(httpSecurity)); } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java index 00f50ca807..83e4205bef 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java @@ -185,6 +185,17 @@ public class OAuth2AuthorizationServerMetadataTests { .andExpect(jsonPath("$.grant_types_supported[4]").value(AuthorizationGrantType.DEVICE_CODE.getValue())); } + @Test + public void requestWhenAuthorizationServerMetadataRequestAndPushedAuthorizationRequestEnabledThenMetadataResponseIncludesPushedAuthorizationRequestEndpoint() + throws Exception { + this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequestEnabled.class).autowire(); + + this.mvc.perform(get(ISSUER.concat(DEFAULT_OAUTH2_AUTHORIZATION_SERVER_METADATA_ENDPOINT_URI))) + .andExpect(status().is2xxSuccessful()) + .andExpect(jsonPath("$.pushed_authorization_request_endpoint") + .value(ISSUER.concat(this.authorizationServerSettings.getPushedAuthorizationRequestEndpoint()))); + } + @EnableWebSecurity @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfiguration { @@ -301,4 +312,26 @@ public class OAuth2AuthorizationServerMetadataTests { } + @EnableWebSecurity + @Configuration(proxyBeanMethods = false) + static class AuthorizationServerConfigurationWithPushedAuthorizationRequestEnabled + extends AuthorizationServerConfiguration { + + // @formatter:off + @Bean + SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + http + .oauth2AuthorizationServer((authorizationServer) -> + authorizationServer + .pushedAuthorizationRequestEndpoint(Customizer.withDefaults()) + ) + .authorizeHttpRequests((authorize) -> + authorize.anyRequest().authenticated() + ); + return http.build(); + } + // @formatter:on + + } + } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcProviderConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcProviderConfigurationTests.java index 69f7182cac..6c33191b53 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcProviderConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcProviderConfigurationTests.java @@ -159,6 +159,18 @@ public class OidcProviderConfigurationTests { .andExpect(jsonPath("$.grant_types_supported[4]").value(AuthorizationGrantType.DEVICE_CODE.getValue())); } + @Test + public void requestWhenConfigurationRequestAndPushedAuthorizationRequestEnabledThenConfigurationResponseIncludesPushedAuthorizationRequestEndpoint() + throws Exception { + this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequestEnabled.class).autowire(); + + this.mvc.perform(get(ISSUER.concat(DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI))) + .andExpect(status().is2xxSuccessful()) + .andExpectAll(defaultConfigurationMatchers(ISSUER)) + .andExpect(jsonPath("$.pushed_authorization_request_endpoint") + .value(ISSUER.concat(this.authorizationServerSettings.getPushedAuthorizationRequestEndpoint()))); + } + private ResultMatcher[] defaultConfigurationMatchers(String issuer) { // @formatter:off return new ResultMatcher[] { @@ -357,6 +369,26 @@ public class OidcProviderConfigurationTests { } + @EnableWebSecurity + @Configuration(proxyBeanMethods = false) + static class AuthorizationServerConfigurationWithPushedAuthorizationRequestEnabled + extends AuthorizationServerConfiguration { + + // @formatter:off + @Bean + SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + http + .oauth2AuthorizationServer((authorizationServer) -> + authorizationServer + .pushedAuthorizationRequestEndpoint(Customizer.withDefaults()) + .oidc(Customizer.withDefaults()) + ); + return http.build(); + } + // @formatter:on + + } + @EnableWebSecurity @Configuration(proxyBeanMethods = false) static class AuthorizationServerConfigurationWithInvalidIssuerUrl extends AuthorizationServerConfiguration { diff --git a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java index eebbfccad4..b10a620ebd 100644 --- a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java +++ b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java @@ -101,8 +101,6 @@ public final class OidcProviderConfigurationEndpointFilter extends OncePerReques OidcProviderConfiguration.Builder providerConfiguration = OidcProviderConfiguration.builder() .issuer(issuer) .authorizationEndpoint(asUrl(issuer, authorizationServerSettings.getAuthorizationEndpoint())) - .pushedAuthorizationRequestEndpoint( - asUrl(issuer, authorizationServerSettings.getPushedAuthorizationRequestEndpoint())) .tokenEndpoint(asUrl(issuer, authorizationServerSettings.getTokenEndpoint())) .tokenEndpointAuthenticationMethods(clientAuthenticationMethods()) .jwkSetUrl(asUrl(issuer, authorizationServerSettings.getJwkSetEndpoint())) diff --git a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java index d5f061cd0f..cf12f4e510 100644 --- a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java +++ b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java @@ -101,8 +101,6 @@ public final class OAuth2AuthorizationServerMetadataEndpointFilter extends OnceP .builder() .issuer(issuer) .authorizationEndpoint(asUrl(issuer, authorizationServerSettings.getAuthorizationEndpoint())) - .pushedAuthorizationRequestEndpoint( - asUrl(issuer, authorizationServerSettings.getPushedAuthorizationRequestEndpoint())) .tokenEndpoint(asUrl(issuer, authorizationServerSettings.getTokenEndpoint())) .tokenEndpointAuthenticationMethods(clientAuthenticationMethods()) .jwkSetUrl(asUrl(issuer, authorizationServerSettings.getJwkSetEndpoint())) diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java index 04d55e6baf..bdc8bb4c4b 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java @@ -134,8 +134,7 @@ public class OidcProviderConfigurationEndpointFilterTests { assertThat(providerConfigurationResponse).contains("\"issuer\":\"https://example.com\""); assertThat(providerConfigurationResponse) .contains("\"authorization_endpoint\":\"https://example.com/oauth2/v1/authorize\""); - assertThat(providerConfigurationResponse) - .contains("\"pushed_authorization_request_endpoint\":\"https://example.com/oauth2/v1/par\""); + assertThat(providerConfigurationResponse).doesNotContain("\"pushed_authorization_request_endpoint\""); assertThat(providerConfigurationResponse).doesNotContain("\"device_authorization_endpoint\""); assertThat(providerConfigurationResponse) .contains("\"token_endpoint\":\"https://example.com/oauth2/v1/token\""); diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java index 3abbe2b8e9..6bb85af462 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java @@ -130,8 +130,7 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests { assertThat(authorizationServerMetadataResponse).contains("\"issuer\":\"https://example.com\""); assertThat(authorizationServerMetadataResponse) .contains("\"authorization_endpoint\":\"https://example.com/oauth2/v1/authorize\""); - assertThat(authorizationServerMetadataResponse) - .contains("\"pushed_authorization_request_endpoint\":\"https://example.com/oauth2/v1/par\""); + assertThat(authorizationServerMetadataResponse).doesNotContain("\"pushed_authorization_request_endpoint\""); assertThat(authorizationServerMetadataResponse).doesNotContain("\"device_authorization_endpoint\""); assertThat(authorizationServerMetadataResponse) .contains("\"token_endpoint\":\"https://example.com/oauth2/v1/token\"");