diff --git a/docs/modules/ROOT/pages/configuration-model.adoc b/docs/modules/ROOT/pages/configuration-model.adoc index 263a79510..674809234 100644 --- a/docs/modules/ROOT/pages/configuration-model.adoc +++ b/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(); } diff --git a/docs/modules/ROOT/pages/core-model-components.adoc b/docs/modules/ROOT/pages/core-model-components.adoc index 333e3faca..03032ce43 100644 --- a/docs/modules/ROOT/pages/core-model-components.adoc +++ b/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(); } diff --git a/docs/modules/ROOT/pages/guides/how-to-userinfo.adoc b/docs/modules/ROOT/pages/guides/how-to-userinfo.adoc index 6f0e8a977..84e04c863 100644 --- a/docs/modules/ROOT/pages/guides/how-to-userinfo.adoc +++ b/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: diff --git a/docs/modules/ROOT/pages/protocol-endpoints.adoc b/docs/modules/ROOT/pages/protocol-endpoints.adoc index 4bdc9abf2..72e5d938c 100644 --- a/docs/modules/ROOT/pages/protocol-endpoints.adoc +++ b/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`] `@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 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 jwkSource) { - return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); -} ----- - -[NOTE] -A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint. diff --git a/docs/src/main/java/sample/extgrant/SecurityConfig.java b/docs/src/main/java/sample/extgrant/SecurityConfig.java index 4effaedb2..1044363b6 100644 --- a/docs/src/main/java/sample/extgrant/SecurityConfig.java +++ b/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.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 @@ SecurityFilterChain authorizationServerSecurityFilterChain( 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(); } diff --git a/docs/src/main/java/sample/gettingstarted/SecurityConfig.java b/docs/src/main/java/sample/gettingstarted/SecurityConfig.java index c1d08b9ad..0d26b3a9e 100644 --- a/docs/src/main/java/sample/gettingstarted/SecurityConfig.java +++ b/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 SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h 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(); diff --git a/docs/src/main/java/sample/pkce/SecurityConfig.java b/docs/src/main/java/sample/pkce/SecurityConfig.java index 045ddc984..d2f33b1d2 100644 --- a/docs/src/main/java/sample/pkce/SecurityConfig.java +++ b/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.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 SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h 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 CorsConfigurationSource corsConfigurationSource() { return source; } -} \ No newline at end of file +} diff --git a/docs/src/main/java/sample/registration/SecurityConfig.java b/docs/src/main/java/sample/registration/SecurityConfig.java index 4a42255ac..b2abc3e96 100644 --- a/docs/src/main/java/sample/registration/SecurityConfig.java +++ b/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 @@ 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(); } diff --git a/docs/src/main/java/sample/sociallogin/SecurityConfig.java b/docs/src/main/java/sample/sociallogin/SecurityConfig.java index 3f466568c..2cae4bc28 100644 --- a/docs/src/main/java/sample/sociallogin/SecurityConfig.java +++ b/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.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 SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h 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(); diff --git a/docs/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java b/docs/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java index d8f6178fb..e76ae0c17 100644 --- a/docs/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java +++ b/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"), diff --git a/docs/src/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java b/docs/src/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java index 35f3b3c73..25c368afa 100644 --- a/docs/src/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java +++ b/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.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 userInfoMapper = (context) -> { // <2> + Function 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(); diff --git a/docs/src/test/java/sample/jpa/JpaTests.java b/docs/src/test/java/sample/jpa/JpaTests.java index 8720383dd..3a8abaaff 100644 --- a/docs/src/test/java/sample/jpa/JpaTests.java +++ b/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 @@ static class AuthorizationServerConfig { @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(); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java index 3af6b56d3..13c35959c 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java +++ b/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.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 jwkSource) { Set jwsAlgs = new HashSet<>(); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerConfigurer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerConfigurer.java index ba991e9cb..73d4b224a 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerConfigurer.java +++ b/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 RequestMatcher getEndpointsMatcher() { } @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 void init(HttpSecurity httpSecurity) { 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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java index d794baf5e..771839e7b 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java +++ b/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.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.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 @@ static class AuthorizationServerConfigurationWithSecurityContextRepository @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 @@ static class AuthorizationServerConfigurationCustomConsentPage extends Authoriza @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 @@ static class AuthorizationServerConfigurationCustomConsentRequest extends Author @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 @@ static class AuthorizationServerConfigurationCustomAuthorizationEndpoint extends @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerMetadataTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerMetadataTests.java index 934894c4e..abe46c787 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerMetadataTests.java +++ b/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.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 @@ static class AuthorizationServerConfigurationWithMetadataCustomizer extends Auth @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ClientCredentialsGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ClientCredentialsGrantTests.java index 034228651..95cee1594 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ClientCredentialsGrantTests.java +++ b/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.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 @@ static class AuthorizationServerConfigurationCustomTokenEndpoint extends Authori @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 @@ SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) th 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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2RefreshTokenGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2RefreshTokenGrantTests.java index 2153b7747..7d8bca819 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2RefreshTokenGrantTests.java +++ b/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.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 @@ SecurityFilterChain authorizationServerSecurityFilterChain( 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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenIntrospectionTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenIntrospectionTests.java index 9f4f95d33..6a4d145d0 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenIntrospectionTests.java +++ b/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.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 @@ static class AuthorizationServerConfigurationCustomTokenIntrospectionEndpoint @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenRevocationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenRevocationTests.java index 55220bded..5c4b34a2d 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2TokenRevocationTests.java +++ b/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.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 @@ static class AuthorizationServerConfigurationCustomTokenRevocationEndpoint @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationTests.java index 6ebf81268..a2fc98fa7 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcClientRegistrationTests.java +++ b/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.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 @@ static class CustomClientRegistrationConfiguration extends AuthorizationServerCo @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 @@ static class CustomClientMetadataConfiguration extends AuthorizationServerConfig @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 @@ static class AuthorizationServerConfiguration { @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java index e187ef478..e857577ad 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java @@ -17,6 +17,10 @@ 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.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.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 @@ static class AuthorizationServerConfiguration { @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 @@ RegisteredClientRepository registeredClientRepository() { return new InMemoryRegisteredClientRepository(registeredClient); } + @Bean + JWKSource jwkSource() { + return new ImmutableJWKSet<>(new JWKSet(TestJwks.DEFAULT_RSA_JWK)); + } + + @Bean + JwtDecoder jwtDecoder(JWKSource jwkSource) { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); + } + @Bean AuthorizationServerSettings authorizationServerSettings() { return AuthorizationServerSettings.builder().issuer(ISSUER).build(); @@ -261,24 +283,19 @@ static class AuthorizationServerConfigurationWithProviderConfigurationCustomizer @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 @@ static class AuthorizationServerConfigurationWithClientRegistrationEnabled @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java index c7dab5e86..cd4de9ffe 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java +++ b/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.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 @@ static class AuthorizationServerConfiguration { @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 @@ static class AuthorizationServerConfigurationWithTokenGenerator extends Authoriz @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 @@ static class AuthorizationServerConfigurationWithCustomRefreshTokenGenerator @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 diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcUserInfoTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcUserInfoTests.java index f39dfa8db..d634ec261 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcUserInfoTests.java +++ b/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.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 @@ static class CustomUserInfoConfiguration extends AuthorizationServerConfiguratio @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 @@ static class AuthorizationServerConfigurationWithSecurityContextRepository @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 @@ static class AuthorizationServerConfiguration { @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(); diff --git a/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index 5ed3a5617..91f82e76c 100644 --- a/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -57,6 +57,8 @@ 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 SecurityFilterChain authorizationServerSecurityFilterChain( 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 SecurityFilterChain authorizationServerSecurityFilterChain( 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(); }