diff --git a/docs/src/docs/asciidoc/configuration-model.adoc b/docs/src/docs/asciidoc/configuration-model.adoc index 32914f9e..89314fa8 100644 --- a/docs/src/docs/asciidoc/configuration-model.adoc +++ b/docs/src/docs/asciidoc/configuration-model.adoc @@ -19,15 +19,10 @@ The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with * xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint] * xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint] * xref:protocol-endpoints.adoc#jwk-set-endpoint[JWK Set endpoint] -* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint] -* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] [NOTE] The JWK Set endpoint is configured *only* if a `JWKSource` `@Bean` is registered. -[NOTE] -The xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] is disabled by default because many deployments do not require dynamic client registration. - The following example shows how to use `OAuth2AuthorizationServerConfiguration` to apply the minimal default configuration: [source,java] @@ -55,6 +50,29 @@ public class AuthorizationServerConfig { [IMPORTANT] The https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant] requires the resource owner to be authenticated. Therefore, a user authentication mechanism *must* be configured in addition to the default OAuth2 security configuration. +https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] is disabled in the default configuration. The following example shows how to enable OpenID Connect 1.0 by initializing the `OidcConfigurer`: + +[source,java] +---- +@Bean +public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); // Initialize `OidcConfigurer` + + return http.build(); +} +---- + +In addition to the default protocol endpoints, the OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following OpenID Connect 1.0 protocol endpoints: + +* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint] +* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] + +[NOTE] +The xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] is disabled by default because many deployments do not require dynamic client registration. + [TIP] `OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource)` is a convenience (`static`) utility method that can be used to register a `JwtDecoder` `@Bean`, which is *REQUIRED* for the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] and the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint]. diff --git a/docs/src/docs/asciidoc/examples/src/main/java/sample/gettingStarted/SecurityConfig.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/gettingStarted/SecurityConfig.java index 3cc9fbf2..b0150df3 100644 --- a/docs/src/docs/asciidoc/examples/src/main/java/sample/gettingStarted/SecurityConfig.java +++ b/docs/src/docs/asciidoc/examples/src/main/java/sample/gettingStarted/SecurityConfig.java @@ -42,6 +42,7 @@ import org.springframework.security.oauth2.server.authorization.client.InMemoryR import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @@ -56,6 +57,8 @@ public class SecurityConfig { public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 // @formatter:off http // Redirect to the login page when not authenticated from the diff --git a/docs/src/docs/asciidoc/examples/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java index 0b30c602..38576afd 100644 --- a/docs/src/docs/asciidoc/examples/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java +++ b/docs/src/docs/asciidoc/examples/src/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java @@ -44,6 +44,7 @@ import org.springframework.security.oauth2.server.authorization.client.InMemoryR import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @@ -57,6 +58,8 @@ public class EnableUserInfoSecurityConfig { @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 // @formatter:off http .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) // <2> diff --git a/docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java index 61b5b094..8e95fbb6 100644 --- a/docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java +++ b/docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java @@ -36,8 +36,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +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.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; import org.springframework.security.oauth2.jwt.JwtDecoder; @@ -49,6 +53,10 @@ import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.test.web.servlet.MockMvc; import org.springframework.util.StringUtils; @@ -133,9 +141,25 @@ public class JpaTests { @EnableWebSecurity @EnableAutoConfiguration @ComponentScan - @Import(OAuth2AuthorizationServerConfiguration.class) 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 + + // @formatter:off + http + .exceptionHandling(exceptions -> + exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")) + ) + .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + // @formatter:on + return http.build(); + } + @Bean public JWKSource jwkSource() { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); @@ -147,6 +171,11 @@ public class JpaTests { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } + @Bean + public AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().build(); + } + } } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationEndpointConfigurer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationEndpointConfigurer.java index 089183c1..bcd4809c 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationEndpointConfigurer.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationEndpointConfigurer.java @@ -28,9 +28,11 @@ import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationContext; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationProvider; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationValidator; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationProvider; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; @@ -65,6 +67,7 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C private AuthenticationSuccessHandler authorizationResponseHandler; private AuthenticationFailureHandler errorResponseHandler; private String consentPage; + private Consumer authorizationCodeRequestAuthenticationValidator; /** * Restrict for internal use only. @@ -189,6 +192,14 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C return this; } + void addAuthorizationCodeRequestAuthenticationValidator( + Consumer authenticationValidator) { + this.authorizationCodeRequestAuthenticationValidator = + this.authorizationCodeRequestAuthenticationValidator == null ? + authenticationValidator : + this.authorizationCodeRequestAuthenticationValidator.andThen(authenticationValidator); + } + @Override void init(HttpSecurity httpSecurity) { AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity); @@ -251,7 +262,7 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C return authenticationConverters; } - private static List createDefaultAuthenticationProviders(HttpSecurity httpSecurity) { + private List createDefaultAuthenticationProviders(HttpSecurity httpSecurity) { List authenticationProviders = new ArrayList<>(); OAuth2AuthorizationCodeRequestAuthenticationProvider authorizationCodeRequestAuthenticationProvider = @@ -259,6 +270,11 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C OAuth2ConfigurerUtils.getRegisteredClientRepository(httpSecurity), OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity), OAuth2ConfigurerUtils.getAuthorizationConsentService(httpSecurity)); + if (this.authorizationCodeRequestAuthenticationValidator != null) { + authorizationCodeRequestAuthenticationProvider.setAuthenticationValidator( + new OAuth2AuthorizationCodeRequestAuthenticationValidator() + .andThen(this.authorizationCodeRequestAuthenticationValidator)); + } authenticationProviders.add(authorizationCodeRequestAuthenticationProvider); OAuth2AuthorizationConsentAuthenticationProvider authorizationConsentAuthenticationProvider = 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 8e9f6332..1468a351 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 @@ -16,7 +16,9 @@ package org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers; import java.net.URI; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import com.nimbusds.jose.jwk.source.JWKSource; @@ -27,9 +29,14 @@ import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.oauth2.core.OAuth2Token; +import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; @@ -68,15 +75,8 @@ public final class OAuth2AuthorizationServerConfigurer extends AbstractHttpConfigurer { private final Map, AbstractOAuth2Configurer> configurers = createConfigurers(); - private final RequestMatcher endpointsMatcher = (request) -> - getRequestMatcher(OAuth2AuthorizationServerMetadataEndpointConfigurer.class).matches(request) || - getRequestMatcher(OAuth2AuthorizationEndpointConfigurer.class).matches(request) || - getRequestMatcher(OAuth2TokenEndpointConfigurer.class).matches(request) || - getRequestMatcher(OAuth2TokenIntrospectionEndpointConfigurer.class).matches(request) || - getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class).matches(request) || - getRequestMatcher(OidcConfigurer.class).matches(request) || - this.jwkSetEndpointMatcher.matches(request); - private RequestMatcher jwkSetEndpointMatcher; + private RequestMatcher endpointsMatcher; + /** * Sets the repository of registered clients. @@ -209,13 +209,18 @@ public final class OAuth2AuthorizationServerConfigurer } /** - * Configures OpenID Connect 1.0 support. + * Configures OpenID Connect 1.0 support (disabled by default). * * @param oidcCustomizer the {@link Customizer} providing access to the {@link OidcConfigurer} * @return the {@link OAuth2AuthorizationServerConfigurer} for further configuration */ public OAuth2AuthorizationServerConfigurer oidc(Customizer oidcCustomizer) { - oidcCustomizer.customize(getConfigurer(OidcConfigurer.class)); + OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class); + if (oidcConfigurer == null) { + addConfigurer(OidcConfigurer.class, new OidcConfigurer(this::postProcess)); + oidcConfigurer = getConfigurer(OidcConfigurer.class); + } + oidcCustomizer.customize(oidcConfigurer); return this; } @@ -225,7 +230,9 @@ public final class OAuth2AuthorizationServerConfigurer * @return a {@link RequestMatcher} for the authorization server endpoints */ public RequestMatcher getEndpointsMatcher() { - return this.endpointsMatcher; + // Return a deferred RequestMatcher + // since endpointsMatcher is constructed in init(HttpSecurity). + return (request) -> this.endpointsMatcher.matches(request); } @Override @@ -233,10 +240,33 @@ public final class OAuth2AuthorizationServerConfigurer AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity); validateAuthorizationServerSettings(authorizationServerSettings); - this.jwkSetEndpointMatcher = new AntPathRequestMatcher( - authorizationServerSettings.getJwkSetEndpoint(), HttpMethod.GET.name()); + OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class); + if (oidcConfigurer == null) { + // OpenID Connect is disabled. + // Add an authentication validator that rejects authentication requests. + OAuth2AuthorizationEndpointConfigurer authorizationEndpointConfigurer = + getConfigurer(OAuth2AuthorizationEndpointConfigurer.class); + authorizationEndpointConfigurer.addAuthorizationCodeRequestAuthenticationValidator((authenticationContext) -> { + OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = + authenticationContext.getAuthentication(); + if (authorizationCodeRequestAuthentication.getScopes().contains(OidcScopes.OPENID)) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_SCOPE, + "OpenID Connect 1.0 authentication requests are restricted.", + "https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1"); + throw new OAuth2AuthorizationCodeRequestAuthenticationException( + error, authorizationCodeRequestAuthentication); + } + }); + } - this.configurers.values().forEach(configurer -> configurer.init(httpSecurity)); + List requestMatchers = new ArrayList<>(); + this.configurers.values().forEach(configurer -> { + configurer.init(httpSecurity); + requestMatchers.add(configurer.getRequestMatcher()); + }); + requestMatchers.add(new AntPathRequestMatcher( + authorizationServerSettings.getJwkSetEndpoint(), HttpMethod.GET.name())); + this.endpointsMatcher = new OrRequestMatcher(requestMatchers); ExceptionHandlingConfigurer exceptionHandling = httpSecurity.getConfigurer(ExceptionHandlingConfigurer.class); if (exceptionHandling != null) { @@ -275,7 +305,6 @@ public final class OAuth2AuthorizationServerConfigurer configurers.put(OAuth2TokenEndpointConfigurer.class, new OAuth2TokenEndpointConfigurer(this::postProcess)); configurers.put(OAuth2TokenIntrospectionEndpointConfigurer.class, new OAuth2TokenIntrospectionEndpointConfigurer(this::postProcess)); configurers.put(OAuth2TokenRevocationEndpointConfigurer.class, new OAuth2TokenRevocationEndpointConfigurer(this::postProcess)); - configurers.put(OidcConfigurer.class, new OidcConfigurer(this::postProcess)); return configurers; } @@ -284,8 +313,13 @@ public final class OAuth2AuthorizationServerConfigurer return (T) this.configurers.get(type); } + private void addConfigurer(Class configurerType, T configurer) { + this.configurers.put(configurerType, configurer); + } + private RequestMatcher getRequestMatcher(Class configurerType) { - return getConfigurer(configurerType).getRequestMatcher(); + T configurer = getConfigurer(configurerType); + return configurer != null ? configurer.getRequestMatcher() : null; } private static void validateAuthorizationServerSettings(AuthorizationServerSettings authorizationServerSettings) { 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 035f5933..83dde861 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 @@ -23,7 +23,6 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -197,9 +196,16 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfiguration { + @Bean + SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 + return http.build(); + } + @Bean RegisteredClientRepository registeredClientRepository() { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); @@ -275,7 +281,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithInvalidIssuerUrl extends AuthorizationServerConfiguration { @Bean @@ -285,7 +290,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithInvalidIssuerUri extends AuthorizationServerConfiguration { @Bean @@ -295,7 +299,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithIssuerQuery extends AuthorizationServerConfiguration { @Bean @@ -305,7 +308,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithIssuerFragment extends AuthorizationServerConfiguration { @Bean @@ -315,7 +317,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithIssuerQueryAndFragment extends AuthorizationServerConfiguration { @Bean @@ -325,7 +326,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithIssuerEmptyQuery extends AuthorizationServerConfiguration { @Bean @@ -335,7 +335,6 @@ public class OidcProviderConfigurationTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfigurationWithIssuerEmptyFragment extends AuthorizationServerConfiguration { @Bean 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 e74b9c8a..669b7389 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 @@ -36,7 +36,6 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; @@ -48,6 +47,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.authentication.TestingAuthenticationToken; +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; @@ -79,6 +79,7 @@ import org.springframework.security.oauth2.server.authorization.client.Registere import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.test.SpringTestRule; import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; @@ -276,9 +277,16 @@ public class OidcTests { } @EnableWebSecurity - @Import(OAuth2AuthorizationServerConfiguration.class) static class AuthorizationServerConfiguration { + @Bean + SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 + return http.build(); + } + @Bean OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); @@ -324,6 +332,11 @@ public class OidcTests { }; } + @Bean + AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().build(); + } + @Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); @@ -360,7 +373,8 @@ public class OidcTests { http.apply(authorizationServerConfigurer); authorizationServerConfigurer - .tokenGenerator(tokenGenerator()); + .tokenGenerator(tokenGenerator()) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); 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 a6cffd79..8e071319 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 @@ -34,6 +34,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; +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.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; @@ -306,6 +307,8 @@ public class OidcUserInfoTests { SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); + authorizationServerConfigurer + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 RequestMatcher endpointsMatcher = authorizationServerConfigurer .getEndpointsMatcher(); @@ -333,6 +336,8 @@ public class OidcUserInfoTests { SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); + authorizationServerConfigurer + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 RequestMatcher endpointsMatcher = authorizationServerConfigurer .getEndpointsMatcher(); diff --git a/samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index 5b92994e..5f7417ba 100644 --- a/samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -27,6 +27,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -61,7 +62,8 @@ public class AuthorizationServerConfig { new OAuth2AuthorizationServerConfigurer(); authorizationServerConfigurer .authorizationEndpoint(authorizationEndpoint -> - authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)); + authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 RequestMatcher endpointsMatcher = authorizationServerConfigurer .getEndpointsMatcher(); diff --git a/samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index d209fca4..742fa6cd 100644 --- a/samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -31,6 +31,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -45,6 +46,7 @@ import org.springframework.security.oauth2.server.authorization.client.JdbcRegis import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.web.SecurityFilterChain; @@ -61,6 +63,9 @@ public class AuthorizationServerConfig { @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 + // @formatter:off http .exceptionHandling(exceptions -> diff --git a/samples/federated-identity-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/federated-identity-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index 23e6ab75..04cb54e5 100644 --- a/samples/federated-identity-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/federated-identity-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -33,6 +33,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -47,6 +48,7 @@ import org.springframework.security.oauth2.server.authorization.client.JdbcRegis import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; @@ -64,6 +66,8 @@ public class AuthorizationServerConfig { @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 http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); http.apply(new FederatedIdentityConfigurer()); return http.build();