From e6f602cec0b8ec0da30d97099189448698111cad Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Tue, 21 Mar 2023 16:34:49 -0700 Subject: [PATCH] Polish "Add Spring Authorization Server support" See gh-34003 --- ...onServerPropertiesRegistrationAdapter.java | 68 ++----- ...2AuthorizationServerAutoConfiguration.java | 9 +- ...uth2AuthorizationServerConfiguration.java} | 2 +- ...thorizationServerJwtAutoConfiguration.java | 65 +++++- ...h2AuthorizationServerJwtConfiguration.java | 87 -------- ...izationServerWebSecurityConfiguration.java | 4 + .../servlet/SecurityAutoConfiguration.java | 2 +- ...verPropertiesRegistrationAdapterTests.java | 9 +- ...nServerPropertiesSettingsAdapterTests.java | 5 +- ...th2AuthorizationServerPropertiesTests.java | 2 +- ...orizationServerAutoConfigurationTests.java | 184 +++++++++++++++++ ...zationServerJwtAutoConfigurationTests.java | 107 ++++++++++ ...horizationServerJwtConfigurationTests.java | 110 ---------- ...ionServerPropertiesConfigurationTests.java | 189 ------------------ ...onServerWebSecurityConfigurationTests.java | 134 ++++++++----- .../spring-boot-dependencies/build.gradle | 2 +- ...h2AuthorizationServerApplicationTests.java | 12 +- 17 files changed, 461 insertions(+), 530 deletions(-) rename spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/{OAuth2AuthorizationServerPropertiesConfiguration.java => OAuth2AuthorizationServerConfiguration.java} (98%) delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfiguration.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfigurationTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapter.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapter.java index 7cb9187f80..edebfe8939 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapter.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapter.java @@ -31,7 +31,6 @@ import org.springframework.security.oauth2.server.authorization.client.Registere import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat; import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; -import org.springframework.util.CollectionUtils; /** * Adapter class to convert {@link Client} to a {@link RegisteredClient}. @@ -58,66 +57,23 @@ public final class OAuth2AuthorizationServerPropertiesRegistrationAdapter { map.from(registration::getClientId).to(builder::clientId); map.from(registration::getClientSecret).to(builder::clientSecret); map.from(registration::getClientName).to(builder::clientName); - if (!CollectionUtils.isEmpty(registration.getClientAuthenticationMethods())) { - registration.getClientAuthenticationMethods() - .forEach((clientAuthenticationMethod) -> map.from(clientAuthenticationMethod) - .as(OAuth2AuthorizationServerPropertiesRegistrationAdapter::clientAuthenticationMethod) - .to(builder::clientAuthenticationMethod)); - } - if (!CollectionUtils.isEmpty(registration.getAuthorizationGrantTypes())) { - registration.getAuthorizationGrantTypes() - .forEach((authorizationGrantType) -> map.from(authorizationGrantType) - .as(OAuth2AuthorizationServerPropertiesRegistrationAdapter::authorizationGrantType) - .to(builder::authorizationGrantType)); - } - if (!CollectionUtils.isEmpty(registration.getRedirectUris())) { - registration.getRedirectUris().forEach((redirectUri) -> map.from(redirectUri).to(builder::redirectUri)); - } - if (!CollectionUtils.isEmpty(registration.getPostLogoutRedirectUris())) { - registration.getPostLogoutRedirectUris() - .forEach((redirectUri) -> map.from(redirectUri).to(builder::postLogoutRedirectUri)); - } - if (!CollectionUtils.isEmpty(registration.getScopes())) { - registration.getScopes().forEach((scope) -> map.from(scope).to(builder::scope)); - } + registration.getClientAuthenticationMethods() + .forEach((clientAuthenticationMethod) -> map.from(clientAuthenticationMethod) + .as(ClientAuthenticationMethod::new) + .to(builder::clientAuthenticationMethod)); + registration.getAuthorizationGrantTypes() + .forEach((authorizationGrantType) -> map.from(authorizationGrantType) + .as(AuthorizationGrantType::new) + .to(builder::authorizationGrantType)); + registration.getRedirectUris().forEach((redirectUri) -> map.from(redirectUri).to(builder::redirectUri)); + registration.getPostLogoutRedirectUris() + .forEach((redirectUri) -> map.from(redirectUri).to(builder::postLogoutRedirectUri)); + registration.getScopes().forEach((scope) -> map.from(scope).to(builder::scope)); builder.clientSettings(getClientSettings(client, map)); builder.tokenSettings(getTokenSettings(client, map)); return builder.build(); } - private static ClientAuthenticationMethod clientAuthenticationMethod(String clientAuthenticationMethod) { - if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue().equals(clientAuthenticationMethod)) { - return ClientAuthenticationMethod.CLIENT_SECRET_BASIC; - } - else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.getValue().equals(clientAuthenticationMethod)) { - return ClientAuthenticationMethod.CLIENT_SECRET_POST; - } - else if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.getValue().equals(clientAuthenticationMethod)) { - return ClientAuthenticationMethod.CLIENT_SECRET_JWT; - } - else if (ClientAuthenticationMethod.PRIVATE_KEY_JWT.getValue().equals(clientAuthenticationMethod)) { - return ClientAuthenticationMethod.PRIVATE_KEY_JWT; - } - else if (ClientAuthenticationMethod.NONE.getValue().equals(clientAuthenticationMethod)) { - return ClientAuthenticationMethod.NONE; - } - else { - return new ClientAuthenticationMethod(clientAuthenticationMethod); - } - } - - private static AuthorizationGrantType authorizationGrantType(String authorizationGrantType) { - if (AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(authorizationGrantType)) { - return AuthorizationGrantType.AUTHORIZATION_CODE; - } - else if (AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equals(authorizationGrantType)) { - return AuthorizationGrantType.CLIENT_CREDENTIALS; - } - else { - return new AuthorizationGrantType(authorizationGrantType); - } - } - private static ClientSettings getClientSettings(Client client, PropertyMapper map) { ClientSettings.Builder builder = ClientSettings.builder(); map.from(client::isRequireProofKey).to(builder::requireProofKey); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java index 6720564014..1f011a9d8e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java @@ -21,10 +21,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Import; -import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; /** @@ -43,11 +42,11 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat * @since 3.1.0 * @see OAuth2AuthorizationServerJwtAutoConfiguration */ -@AutoConfiguration(before = { OAuth2ResourceServerAutoConfiguration.class, SecurityFilterAutoConfiguration.class }) +@AutoConfiguration(before = { OAuth2ResourceServerAutoConfiguration.class, SecurityAutoConfiguration.class, + UserDetailsServiceAutoConfiguration.class }) @ConditionalOnClass(OAuth2Authorization.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@Import({ OAuth2AuthorizationServerPropertiesConfiguration.class, - OAuth2AuthorizationServerWebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class }) +@Import({ OAuth2AuthorizationServerConfiguration.class, OAuth2AuthorizationServerWebSecurityConfiguration.class }) public class OAuth2AuthorizationServerAutoConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfiguration.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java index b3495cbcc9..691303122f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java @@ -40,7 +40,7 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori */ @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(OAuth2AuthorizationServerProperties.class) -class OAuth2AuthorizationServerPropertiesConfiguration { +class OAuth2AuthorizationServerConfiguration { @Bean @ConditionalOnMissingBean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java index 2b4e95bb56..71251ed0aa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java @@ -16,13 +16,30 @@ package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.UUID; + +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.source.ImmutableJWKSet; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.proc.SecurityContext; + +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; -import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Role; +import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; /** * {@link EnableAutoConfiguration Auto-configuration} for JWT support for endpoints of the @@ -30,12 +47,52 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat * * @author Steve Riesenberg * @since 3.1.0 - * @see OAuth2AuthorizationServerAutoConfiguration */ -@AutoConfiguration(after = { UserDetailsServiceAutoConfiguration.class }) +@AutoConfiguration(after = UserDetailsServiceAutoConfiguration.class) @ConditionalOnClass(OAuth2Authorization.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@Import(OAuth2AuthorizationServerJwtConfiguration.class) public class OAuth2AuthorizationServerJwtAutoConfiguration { + @Bean + @ConditionalOnClass(JwtDecoder.class) + @ConditionalOnMissingBean + JwtDecoder jwtDecoder(JWKSource jwkSource) { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); + } + + @Bean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + @ConditionalOnMissingBean + JWKSource jwkSource() { + RSAKey rsaKey = getRsaKey(); + JWKSet jwkSet = new JWKSet(rsaKey); + return new ImmutableJWKSet<>(jwkSet); + } + + private static RSAKey getRsaKey() { + KeyPair keyPair = generateRsaKey(); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + // @formatter:off + RSAKey rsaKey = new RSAKey.Builder(publicKey) + .privateKey(privateKey) + .keyID(UUID.randomUUID().toString()) + .build(); + // @formatter:on + return rsaKey; + } + + private static KeyPair generateRsaKey() { + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + keyPair = keyPairGenerator.generateKeyPair(); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfiguration.java deleted file mode 100644 index 8809ea029c..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfiguration.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-2023 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.UUID; - -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jose.jwk.RSAKey; -import com.nimbusds.jose.jwk.source.ImmutableJWKSet; -import com.nimbusds.jose.jwk.source.JWKSource; -import com.nimbusds.jose.proc.SecurityContext; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Role; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; - -/** - * {@link Configuration @Configuration} for JWT support for endpoints of the OAuth2 - * authorization server that require it (e.g. User Info, Client Registration). - * - * @author Steve Riesenberg - */ -@Configuration(proxyBeanMethods = false) -class OAuth2AuthorizationServerJwtConfiguration { - - @Bean - @ConditionalOnClass(JwtDecoder.class) - @ConditionalOnMissingBean - JwtDecoder jwtDecoder(JWKSource jwkSource) { - return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); - } - - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - @ConditionalOnClass(JWKSource.class) - @ConditionalOnMissingBean - JWKSource jwkSource() { - KeyPair keyPair = generateRsaKey(); - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); - // @formatter:off - RSAKey rsaKey = new RSAKey.Builder(publicKey) - .privateKey(privateKey) - .keyID(UUID.randomUUID().toString()) - .build(); - // @formatter:on - JWKSet jwkSet = new JWKSet(rsaKey); - return new ImmutableJWKSet<>(jwkSet); - } - - private static KeyPair generateRsaKey() { - KeyPair keyPair; - try { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(2048); - keyPair = keyPairGenerator.generateKeyPair(); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - return keyPair; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java index 6800b61c51..37a496a938 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; @@ -25,8 +26,10 @@ 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.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; @@ -37,6 +40,7 @@ import org.springframework.security.web.authentication.LoginUrlAuthenticationEnt */ @Configuration(proxyBeanMethods = false) @ConditionalOnDefaultWebSecurity +@ConditionalOnBean({ RegisteredClientRepository.class, AuthorizationServerSettings.class }) class OAuth2AuthorizationServerWebSecurityConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java index d5490ebeb1..fcfb70fcca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java @@ -37,7 +37,7 @@ import org.springframework.security.authentication.DefaultAuthenticationEventPub * @author Madhura Bhave * @since 1.0.0 */ -@AutoConfiguration +@AutoConfiguration(before = UserDetailsServiceAutoConfiguration.class) @ConditionalOnClass(DefaultAuthenticationEventPublisher.class) @EnableConfigurationProperties(SecurityProperties.class) @Import({ SpringBootWebSecurityConfiguration.class, SecurityDataConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapterTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapterTests.java index 04ff163ca5..6b3bd4bbf0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapterTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesRegistrationAdapterTests.java @@ -34,18 +34,16 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Steve Riesenberg */ -public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests { +class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests { @Test void getRegisteredClientsWhenValidParametersShouldAdapt() { OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties(); OAuth2AuthorizationServerProperties.Client client = createClient(); properties.getClient().put("foo", client); - List registeredClients = OAuth2AuthorizationServerPropertiesRegistrationAdapter .getRegisteredClients(properties); assertThat(registeredClients).hasSize(1); - RegisteredClient registeredClient = registeredClients.get(0); assertThat(registeredClient.getClientId()).isEqualTo("foo"); assertThat(registeredClient.getClientSecret()).isEqualTo("secret"); @@ -56,13 +54,11 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests { assertThat(registeredClient.getRedirectUris()).containsExactly("https://example.com/redirect"); assertThat(registeredClient.getPostLogoutRedirectUris()).containsExactly("https://example.com/logout"); assertThat(registeredClient.getScopes()).containsExactly("user.read"); - assertThat(registeredClient.getClientSettings().isRequireProofKey()).isTrue(); assertThat(registeredClient.getClientSettings().isRequireAuthorizationConsent()).isTrue(); assertThat(registeredClient.getClientSettings().getJwkSetUrl()).isEqualTo("https://example.com/jwks"); assertThat(registeredClient.getClientSettings().getTokenEndpointAuthenticationSigningAlgorithm()) .isEqualTo(SignatureAlgorithm.RS256); - assertThat(registeredClient.getTokenSettings().getAccessTokenFormat()).isEqualTo(OAuth2TokenFormat.REFERENCE); assertThat(registeredClient.getTokenSettings().getAccessTokenTimeToLive()).isEqualTo(Duration.ofSeconds(300)); assertThat(registeredClient.getTokenSettings().getRefreshTokenTimeToLive()).isEqualTo(Duration.ofHours(24)); @@ -77,7 +73,6 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests { client.setRequireAuthorizationConsent(true); client.setJwkSetUri("https://example.com/jwks"); client.setTokenEndpointAuthenticationSigningAlgorithm("rs256"); - OAuth2AuthorizationServerProperties.Registration registration = client.getRegistration(); registration.setClientId("foo"); registration.setClientSecret("secret"); @@ -86,14 +81,12 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests { registration.getRedirectUris().add("https://example.com/redirect"); registration.getPostLogoutRedirectUris().add("https://example.com/logout"); registration.getScopes().add("user.read"); - OAuth2AuthorizationServerProperties.Token token = client.getToken(); token.setAccessTokenFormat("reference"); token.setAccessTokenTimeToLive(Duration.ofSeconds(300)); token.setRefreshTokenTimeToLive(Duration.ofHours(24)); token.setReuseRefreshTokens(true); token.setIdTokenSignatureAlgorithm("rs512"); - return client; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesSettingsAdapterTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesSettingsAdapterTests.java index 476c47001b..0ccde3864f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesSettingsAdapterTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesSettingsAdapterTests.java @@ -27,12 +27,11 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Steve Riesenberg */ -public class OAuth2AuthorizationServerPropertiesSettingsAdapterTests { +class OAuth2AuthorizationServerPropertiesSettingsAdapterTests { @Test void getAuthorizationServerSettingsWhenValidParametersShouldAdapt() { OAuth2AuthorizationServerProperties properties = createAuthorizationServerProperties(); - AuthorizationServerSettings settings = OAuth2AuthorizationServerPropertiesSettingsAdapter .getAuthorizationServerSettings(properties); assertThat(settings.getIssuer()).isEqualTo("https://example.com"); @@ -49,14 +48,12 @@ public class OAuth2AuthorizationServerPropertiesSettingsAdapterTests { private OAuth2AuthorizationServerProperties createAuthorizationServerProperties() { OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties(); properties.setIssuer("https://example.com"); - OAuth2AuthorizationServerProperties.Endpoint endpoints = properties.getEndpoint(); endpoints.setAuthorizationUri("/authorize"); endpoints.setTokenUri("/token"); endpoints.setJwkSetUri("/jwks"); endpoints.setTokenRevocationUri("/revoke"); endpoints.setTokenIntrospectionUri("/introspect"); - OAuth2AuthorizationServerProperties.OidcEndpoint oidc = endpoints.getOidc(); oidc.setLogoutUri("/logout"); oidc.setClientRegistrationUri("/register"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesTests.java index 27b18c2eb1..5009a11217 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/OAuth2AuthorizationServerPropertiesTests.java @@ -25,7 +25,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * * @author Steve Riesenberg */ -public class OAuth2AuthorizationServerPropertiesTests { +class OAuth2AuthorizationServerPropertiesTests { private final OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java new file mode 100644 index 0000000000..947962e625 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java @@ -0,0 +1,184 @@ +/* + * Copyright 2012-2023 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +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.settings.AuthorizationServerSettings; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link OAuth2AuthorizationServerAutoConfiguration}. + * + * @author Steve Riesenberg + * @author Madhura Bhave + */ +class OAuth2AuthorizationServerAutoConfigurationTests { + + private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver"; + + private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client"; + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OAuth2AuthorizationServerAutoConfiguration.class, + OAuth2AuthorizationServerJwtAutoConfiguration.class, SecurityAutoConfiguration.class, + UserDetailsServiceAutoConfiguration.class)); + + @Test + void autoConfigurationConditionalOnClassOauth2Authorization() { + this.contextRunner.withClassLoader(new FilteredClassLoader(OAuth2Authorization.class)) + .run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerAutoConfiguration.class)); + } + + @Test + void autoConfigurationDoesNotCauseUserDetailsServiceToBackOff() { + this.contextRunner.run((context) -> assertThat(context).hasBean("inMemoryUserDetailsManager")); + } + + @Test + void registeredClientRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(RegisteredClientRepository.class)); + } + + @Test + void registeredClientRepositoryBeanShouldBeCreatedWhenPropertiesPresent() { + this.contextRunner + .withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd", + CLIENT_PREFIX + ".foo.registration.client-secret=secret", + CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", + CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", + CLIENT_PREFIX + ".foo.registration.scopes=test") + .run((context) -> { + RegisteredClientRepository registeredClientRepository = context + .getBean(RegisteredClientRepository.class); + RegisteredClient registeredClient = registeredClientRepository.findById("foo"); + assertThat(registeredClient).isNotNull(); + assertThat(registeredClient.getClientId()).isEqualTo("abcd"); + assertThat(registeredClient.getClientSecret()).isEqualTo("secret"); + assertThat(registeredClient.getClientAuthenticationMethods()) + .containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); + assertThat(registeredClient.getAuthorizationGrantTypes()) + .containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS); + assertThat(registeredClient.getScopes()).containsOnly("test"); + }); + } + + @Test + void registeredClientRepositoryBacksOffWhenRegisteredClientRepositoryBeanPresent() { + this.contextRunner.withUserConfiguration(TestRegisteredClientRepositoryConfiguration.class) + .withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd", + CLIENT_PREFIX + ".foo.registration.client-secret=secret", + CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", + CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", + CLIENT_PREFIX + ".foo.registration.scope=test") + .run((context) -> { + RegisteredClientRepository registeredClientRepository = context + .getBean(RegisteredClientRepository.class); + RegisteredClient registeredClient = registeredClientRepository.findById("test"); + assertThat(registeredClient).isNotNull(); + assertThat(registeredClient.getClientId()).isEqualTo("abcd"); + assertThat(registeredClient.getClientSecret()).isEqualTo("secret"); + assertThat(registeredClient.getClientAuthenticationMethods()) + .containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); + assertThat(registeredClient.getAuthorizationGrantTypes()) + .containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS); + assertThat(registeredClient.getScopes()).containsOnly("test"); + }); + } + + @Test + void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesAbsent() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(AuthorizationServerSettings.class)); + } + + @Test + void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesPresent() { + this.contextRunner + .withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://example.com", + PROPERTIES_PREFIX + ".endpoint.authorization-uri=/authorize", + PROPERTIES_PREFIX + ".endpoint.token-uri=/token", PROPERTIES_PREFIX + ".endpoint.jwk-set-uri=/jwks", + PROPERTIES_PREFIX + ".endpoint.token-revocation-uri=/revoke", + PROPERTIES_PREFIX + ".endpoint.token-introspection-uri=/introspect", + PROPERTIES_PREFIX + ".endpoint.oidc.logout-uri=/logout", + PROPERTIES_PREFIX + ".endpoint.oidc.client-registration-uri=/register", + PROPERTIES_PREFIX + ".endpoint.oidc.user-info-uri=/user") + .run((context) -> { + AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class); + assertThat(settings.getIssuer()).isEqualTo("https://example.com"); + assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize"); + assertThat(settings.getTokenEndpoint()).isEqualTo("/token"); + assertThat(settings.getJwkSetEndpoint()).isEqualTo("/jwks"); + assertThat(settings.getTokenRevocationEndpoint()).isEqualTo("/revoke"); + assertThat(settings.getTokenIntrospectionEndpoint()).isEqualTo("/introspect"); + assertThat(settings.getOidcLogoutEndpoint()).isEqualTo("/logout"); + assertThat(settings.getOidcClientRegistrationEndpoint()).isEqualTo("/register"); + assertThat(settings.getOidcUserInfoEndpoint()).isEqualTo("/user"); + }); + } + + @Test + void authorizationServerSettingsBacksOffWhenAuthorizationServerSettingsBeanPresent() { + this.contextRunner.withUserConfiguration(TestAuthorizationServerSettingsConfiguration.class) + .withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://test.com") + .run((context) -> { + AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class); + assertThat(settings.getIssuer()).isEqualTo("https://example.com"); + }); + } + + @Configuration + static class TestRegisteredClientRepositoryConfiguration { + + @Bean + RegisteredClientRepository registeredClientRepository() { + RegisteredClient registeredClient = RegisteredClient.withId("test") + .clientId("abcd") + .clientSecret("secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .scope("test") + .build(); + return new InMemoryRegisteredClientRepository(registeredClient); + } + + } + + @Configuration + static class TestAuthorizationServerSettingsConfiguration { + + @Bean + AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().issuer("https://example.com").build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java new file mode 100644 index 0000000000..feecee8570 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2023 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; + +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.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2AuthorizationServerJwtAutoConfiguration}. + * + * @author Steve Riesenberg + */ +class OAuth2AuthorizationServerJwtAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OAuth2AuthorizationServerJwtAutoConfiguration.class)); + + @Test + void autoConfigurationConditionalOnClassOauth2Authorization() { + this.contextRunner.withClassLoader(new FilteredClassLoader(OAuth2Authorization.class)) + .run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerJwtAutoConfiguration.class)); + } + + @Test + void jwtDecoderConditionalOnClassJwtDecoder() { + this.contextRunner.withClassLoader(new FilteredClassLoader(JwtDecoder.class)) + .run((context) -> assertThat(context).doesNotHaveBean("jwtDecoder")); + } + + @Test + void jwtConfigurationConfiguresJwtDecoderWithGeneratedKey() { + this.contextRunner.run((context) -> { + assertThat(context).hasBean("jwtDecoder"); + assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class); + assertThat(context).hasBean("jwkSource"); + assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class); + }); + } + + @Test + void jwtDecoderBacksOffWhenBeanPresent() { + this.contextRunner.withUserConfiguration(TestJwtDecoderConfiguration.class).run((context) -> { + assertThat(context).hasBean("jwtDecoder"); + assertThat(context.getBean("jwtDecoder")).isNotInstanceOf(NimbusJwtDecoder.class); + assertThat(context).hasBean("jwkSource"); + assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class); + }); + } + + @Test + void jwkSourceBacksOffWhenBeanPresent() { + this.contextRunner.withUserConfiguration(TestJwkSourceConfiguration.class).run((context) -> { + assertThat(context).hasBean("jwtDecoder"); + assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class); + assertThat(context).hasBean("jwkSource"); + assertThat(context.getBean("jwkSource")).isNotInstanceOf(ImmutableJWKSet.class); + }); + } + + @Configuration + static class TestJwtDecoderConfiguration { + + @Bean + JwtDecoder jwtDecoder() { + return (token) -> null; + } + + } + + @Configuration + static class TestJwkSourceConfiguration { + + @Bean + JWKSource jwkSource() { + return (jwkSelector, context) -> null; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfigurationTests.java deleted file mode 100644 index dd2d562932..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtConfigurationTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2023 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; - -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.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link OAuth2AuthorizationServerJwtConfiguration}. - * - * @author Steve Riesenberg - */ -public class OAuth2AuthorizationServerJwtConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); - - @Test - void jwtConfigurationConfiguresJwtDecoderWithGeneratedKey() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestJwtConfiguration.class) - .run((context) -> { - assertThat(context).hasBean("jwtDecoder"); - assertThat(context).hasBean("jwkSource"); - - assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class); - assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class); - }); - // @formatter:on - } - - @Test - void jwtDecoderBacksOffWhenBeanPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestJwtDecoderConfiguration.class, TestJwtConfiguration.class) - .run((context) -> { - assertThat(context).hasBean("jwtDecoder"); - assertThat(context).hasBean("jwkSource"); - - assertThat(context.getBean("jwtDecoder")).isNotInstanceOf(NimbusJwtDecoder.class); - assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class); - }); - // @formatter:on - } - - @Test - void jwkSourceBacksOffWhenBeanPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestJwkSourceConfiguration.class, TestJwtConfiguration.class) - .run((context) -> { - assertThat(context).hasBean("jwtDecoder"); - assertThat(context).hasBean("jwkSource"); - - assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class); - assertThat(context.getBean("jwkSource")).isNotInstanceOf(ImmutableJWKSet.class); - }); - // @formatter:on - } - - @Configuration - @Import(OAuth2AuthorizationServerJwtConfiguration.class) - static class TestJwtConfiguration { - - } - - @Configuration - static class TestJwtDecoderConfiguration { - - @Bean - JwtDecoder jwtDecoder() { - return (token) -> null; - } - - } - - @Configuration - static class TestJwkSourceConfiguration { - - @Bean - JWKSource jwkSource() { - return (jwkSelector, context) -> null; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfigurationTests.java deleted file mode 100644 index ee552cc571..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesConfigurationTests.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2012-2023 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; -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.settings.AuthorizationServerSettings; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Steve Riesenberg - */ -public class OAuth2AuthorizationServerPropertiesConfigurationTests { - - private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver"; - - private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client"; - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); - - @Test - void registeredClientRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(RegisteredClientRepository.class)); - // @formatter:on - } - - @Test - void registeredClientRepositoryBeanShouldBeCreatedWhenPropertiesPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues( - CLIENT_PREFIX + ".foo.registration.client-id=abcd", - CLIENT_PREFIX + ".foo.registration.client-secret=secret", - CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", - CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", - CLIENT_PREFIX + ".foo.registration.scopes=test") - .run((context) -> { - RegisteredClientRepository registeredClientRepository = context.getBean(RegisteredClientRepository.class); - RegisteredClient registeredClient = registeredClientRepository.findById("foo"); - assertThat(registeredClient).isNotNull(); - assertThat(registeredClient.getClientId()).isEqualTo("abcd"); - assertThat(registeredClient.getClientSecret()).isEqualTo("secret"); - assertThat(registeredClient.getClientAuthenticationMethods()) - .containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); - assertThat(registeredClient.getAuthorizationGrantTypes()) - .containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS); - assertThat(registeredClient.getScopes()).containsOnly("test"); - }); - // @formatter:on - } - - @Test - void registeredClientRepositoryBacksOffWhenRegisteredClientRepositoryBeanPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestRegisteredClientRepositoryConfiguration.class, - TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues( - CLIENT_PREFIX + ".foo.registration.client-id=abcd", - CLIENT_PREFIX + ".foo.registration.client-secret=secret", - CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", - CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", - CLIENT_PREFIX + ".foo.registration.scope=test") - .run((context) -> { - RegisteredClientRepository registeredClientRepository = context.getBean(RegisteredClientRepository.class); - RegisteredClient registeredClient = registeredClientRepository.findById("test"); - assertThat(registeredClient).isNotNull(); - assertThat(registeredClient.getClientId()).isEqualTo("abcd"); - assertThat(registeredClient.getClientSecret()).isEqualTo("secret"); - assertThat(registeredClient.getClientAuthenticationMethods()) - .containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); - assertThat(registeredClient.getAuthorizationGrantTypes()) - .containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS); - assertThat(registeredClient.getScopes()).containsOnly("test"); - }); - // @formatter:on - } - - @Test - void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesAbsent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(AuthorizationServerSettings.class)); - // @formatter:on - } - - @Test - void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues( - PROPERTIES_PREFIX + ".issuer=https://example.com", - PROPERTIES_PREFIX + ".endpoint.authorization-uri=/authorize", - PROPERTIES_PREFIX + ".endpoint.token-uri=/token", - PROPERTIES_PREFIX + ".endpoint.jwk-set-uri=/jwks", - PROPERTIES_PREFIX + ".endpoint.token-revocation-uri=/revoke", - PROPERTIES_PREFIX + ".endpoint.token-introspection-uri=/introspect", - PROPERTIES_PREFIX + ".endpoint.oidc.logout-uri=/logout", - PROPERTIES_PREFIX + ".endpoint.oidc.client-registration-uri=/register", - PROPERTIES_PREFIX + ".endpoint.oidc.user-info-uri=/user") - .run((context) -> { - AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class); - assertThat(settings.getIssuer()).isEqualTo("https://example.com"); - assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize"); - assertThat(settings.getTokenEndpoint()).isEqualTo("/token"); - assertThat(settings.getJwkSetEndpoint()).isEqualTo("/jwks"); - assertThat(settings.getTokenRevocationEndpoint()).isEqualTo("/revoke"); - assertThat(settings.getTokenIntrospectionEndpoint()).isEqualTo("/introspect"); - assertThat(settings.getOidcLogoutEndpoint()).isEqualTo("/logout"); - assertThat(settings.getOidcClientRegistrationEndpoint()).isEqualTo("/register"); - assertThat(settings.getOidcUserInfoEndpoint()).isEqualTo("/user"); - }); - // @formatter:on - } - - @Test - void authorizationServerSettingsBacksOffWhenAuthorizationServerSettingsBeanPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestAuthorizationServerSettingsConfiguration.class, - TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://test.com") - .run((context) -> { - AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class); - assertThat(settings.getIssuer()).isEqualTo("https://example.com"); - }); - // @formatter:on - } - - @Configuration - @EnableWebSecurity - @Import({ OAuth2AuthorizationServerPropertiesConfiguration.class }) - static class TestOAuth2AuthorizationServerConfiguration { - - } - - @Configuration - static class TestRegisteredClientRepositoryConfiguration { - - @Bean - RegisteredClientRepository registeredClientRepository() { - RegisteredClient registeredClient = RegisteredClient.withId("test") - .clientId("abcd") - .clientSecret("secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .scope("test") - .build(); - return new InMemoryRegisteredClientRepository(registeredClient); - } - - } - - @Configuration - static class TestAuthorizationServerSettingsConfiguration { - - @Bean - AuthorizationServerSettings authorizationServerSettings() { - return AuthorizationServerSettings.builder().issuer("https://example.com").build(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java index 3276fa42d7..dbf32229a9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java @@ -21,8 +21,8 @@ import java.util.List; import jakarta.servlet.Filter; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -31,10 +31,16 @@ import org.springframework.security.config.BeanIds; 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.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +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.oidc.web.OidcClientRegistrationEndpointFilter; import org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter; import org.springframework.security.oauth2.server.authorization.oidc.web.OidcUserInfoEndpointFilter; +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter; import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationServerMetadataEndpointFilter; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter; @@ -49,74 +55,69 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera import static org.assertj.core.api.Assertions.assertThat; /** + * Tests for {@link OAuth2AuthorizationServerWebSecurityConfiguration}. + * * @author Steve Riesenberg */ -public class OAuth2AuthorizationServerWebSecurityConfigurationTests { +class OAuth2AuthorizationServerWebSecurityConfigurationTests { private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver"; private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client"; - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(); @Test void webSecurityConfigurationConfiguresAuthorizationServerWithFormLogin() { - // @formatter:off this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues( - CLIENT_PREFIX + ".foo.registration.client-id=abcd", - CLIENT_PREFIX + ".foo.registration.client-secret=secret", - CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", - CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", - CLIENT_PREFIX + ".foo.registration.scopes=test") - .run((context) -> { - assertThat(context).hasBean("authorizationServerSecurityFilterChain"); - assertThat(context).hasBean("defaultSecurityFilterChain"); - assertThat(context).hasBean("registeredClientRepository"); - assertThat(context).hasBean("authorizationServerSettings"); - - assertThat(findFilter(context, OAuth2AuthorizationEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OAuth2TokenEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OAuth2TokenIntrospectionEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OAuth2TokenRevocationEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OAuth2AuthorizationServerMetadataEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OidcProviderConfigurationEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OidcUserInfoEndpointFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNotNull(); - assertThat(findFilter(context, OidcClientRegistrationEndpointFilter.class, 0)).isNull(); - assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 0)).isNull(); - assertThat(findFilter(context, DefaultLoginPageGeneratingFilter.class, 1)).isNotNull(); - assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNotNull(); - }); - // @formatter:on + .withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd", + CLIENT_PREFIX + ".foo.registration.client-secret=secret", + CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", + CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", + CLIENT_PREFIX + ".foo.registration.scopes=test") + .run((context) -> { + assertThat(context).hasBean("authorizationServerSecurityFilterChain"); + assertThat(context).hasBean("defaultSecurityFilterChain"); + assertThat(context).hasBean("registeredClientRepository"); + assertThat(context).hasBean("authorizationServerSettings"); + assertThat(findFilter(context, OAuth2AuthorizationEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OAuth2TokenEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OAuth2TokenIntrospectionEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OAuth2TokenRevocationEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OAuth2AuthorizationServerMetadataEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OidcProviderConfigurationEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OidcUserInfoEndpointFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNotNull(); + assertThat(findFilter(context, OidcClientRegistrationEndpointFilter.class, 0)).isNull(); + assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 0)).isNull(); + assertThat(findFilter(context, DefaultLoginPageGeneratingFilter.class, 1)).isNotNull(); + assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNotNull(); + }); } @Test void securityFilterChainsBackOffWhenSecurityFilterChainBeanPresent() { - // @formatter:off - this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfiguration.class, - TestOAuth2AuthorizationServerConfiguration.class) - .withPropertyValues( - CLIENT_PREFIX + ".foo.registration.client-id=abcd", - CLIENT_PREFIX + ".foo.registration.client-secret=secret", - CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", - CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", - CLIENT_PREFIX + ".foo.registration.scopes=test") - .run((context) -> { - assertThat(context).hasBean("authServerSecurityFilterChain"); - assertThat(context).doesNotHaveBean("authorizationServerSecurityFilterChain"); - assertThat(context).hasBean("securityFilterChain"); - assertThat(context).doesNotHaveBean("defaultSecurityFilterChain"); - assertThat(context).hasBean("registeredClientRepository"); - assertThat(context).hasBean("authorizationServerSettings"); - - assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNull(); - assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNull(); - }); - // @formatter:on + this.contextRunner + .withUserConfiguration(TestSecurityFilterChainConfiguration.class, + TestOAuth2AuthorizationServerConfiguration.class) + .withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd", + CLIENT_PREFIX + ".foo.registration.client-secret=secret", + CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic", + CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials", + CLIENT_PREFIX + ".foo.registration.scopes=test") + .run((context) -> { + assertThat(context).hasBean("authServerSecurityFilterChain"); + assertThat(context).doesNotHaveBean("authorizationServerSecurityFilterChain"); + assertThat(context).hasBean("securityFilterChain"); + assertThat(context).doesNotHaveBean("defaultSecurityFilterChain"); + assertThat(context).hasBean("registeredClientRepository"); + assertThat(context).hasBean("authorizationServerSettings"); + assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNull(); + assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNull(); + }); } - private Filter findFilter(AssertableApplicationContext context, Class filter, + private Filter findFilter(AssertableWebApplicationContext context, Class filter, int filterChainIndex) { FilterChainProxy filterChain = (FilterChainProxy) context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN); List filterChains = filterChain.getFilterChains(); @@ -126,12 +127,35 @@ public class OAuth2AuthorizationServerWebSecurityConfigurationTests { @Configuration @EnableWebSecurity - @Import({ OAuth2AuthorizationServerPropertiesConfiguration.class, - OAuth2AuthorizationServerWebSecurityConfiguration.class, OAuth2AuthorizationServerJwtConfiguration.class }) + @Import({ TestRegisteredClientRepositoryConfiguration.class, + OAuth2AuthorizationServerWebSecurityConfiguration.class, + OAuth2AuthorizationServerJwtAutoConfiguration.class }) static class TestOAuth2AuthorizationServerConfiguration { } + @Configuration + static class TestRegisteredClientRepositoryConfiguration { + + @Bean + RegisteredClientRepository registeredClientRepository() { + RegisteredClient registeredClient = RegisteredClient.withId("test") + .clientId("abcd") + .clientSecret("secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .scope("test") + .build(); + return new InMemoryRegisteredClientRepository(registeredClient); + } + + @Bean + AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().issuer("https://example.com").build(); + } + + } + @Configuration @EnableWebSecurity static class TestSecurityFilterChainConfiguration { diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 8568aef17d..e03296ac6c 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1336,7 +1336,7 @@ bom { ] } } - library("Spring Authorization Server", "1.1.0-M1") { + library("Spring Authorization Server", "1.1.0-M2") { group("org.springframework.security") { modules = [ "spring-security-oauth2-authorization-server" diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java index d1616700f5..ce2d7b75f0 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java @@ -102,18 +102,14 @@ class SampleOAuth2AuthorizationServerApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setBasicAuth("messaging-client", "secret"); HttpEntity request = new HttpEntity<>(headers); - // @formatter:off String requestUri = UriComponentsBuilder.fromUriString("/token") - .queryParam(OAuth2ParameterNames.CLIENT_ID, "messaging-client") - .queryParam(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue()) - .queryParam(OAuth2ParameterNames.SCOPE, "message.read+message.write") - .toUriString(); - // @formatter:on - + .queryParam(OAuth2ParameterNames.CLIENT_ID, "messaging-client") + .queryParam(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue()) + .queryParam(OAuth2ParameterNames.SCOPE, "message.read+message.write") + .toUriString(); ResponseEntity> entity = this.restTemplate.exchange(requestUri, HttpMethod.POST, request, MAP_TYPE_REFERENCE); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - Map tokenResponse = Objects.requireNonNull(entity.getBody()); assertThat(tokenResponse.get(OAuth2ParameterNames.ACCESS_TOKEN)).isNotNull(); assertThat(tokenResponse.get(OAuth2ParameterNames.EXPIRES_IN)).isNotNull();