diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 0eabc5176cc7..e1db586b5f41 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -7,6 +7,7 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module. #### Bugs Fixed - Fix the issue that `AzureMessagingListenerAutoConfiguration` not included in spring.factories [#34690](https://github.com/Azure/azure-sdk-for-java/issues/34690), [#35717](https://github.com/Azure/azure-sdk-for-java/pull/35717). +- Improve default AAD configuration condition [#36126](https://github.com/Azure/azure-sdk-for-java/pull/36126). ## 5.3.0 (2023-06-28) - This release is compatible with Spring Boot 3.0.0-3.1.0. (Note: 3.0.x (x>1) should be supported, but they aren't tested with this release.) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfiguration.java index d8b01d692430..d4b299c70ca6 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfiguration.java @@ -4,14 +4,15 @@ import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.conditions.ResourceServerCondition; +import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; +import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadResourceServerProperties; import com.azure.spring.cloud.autoconfigure.implementation.aad.security.constants.AadJwtClaimNames; import com.azure.spring.cloud.autoconfigure.implementation.aad.security.jwt.AadJwtIssuerValidator; -import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; import com.azure.spring.cloud.autoconfigure.implementation.aad.security.properties.AadAuthorizationServerEndpoints; -import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadResourceServerProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -78,7 +79,7 @@ List> createDefaultValidator(AadAuthenticationProperti @EnableWebSecurity @EnableMethodSecurity - @ConditionalOnMissingBean(SecurityFilterChain.class) + @ConditionalOnDefaultWebSecurity @ConditionalOnExpression("!'${spring.cloud.azure.active-directory.application-type}'.equalsIgnoreCase('web_application_and_resource_server')") static class DefaultAadResourceServerConfiguration { diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfiguration.java index 437f694ebe3a..72aac5bf76cd 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfiguration.java @@ -4,10 +4,11 @@ package com.azure.spring.cloud.autoconfigure.implementation.aad.configuration; import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.conditions.WebApplicationCondition; -import com.azure.spring.cloud.autoconfigure.implementation.aad.security.AadOAuth2UserService; import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; +import com.azure.spring.cloud.autoconfigure.implementation.aad.security.AadOAuth2UserService; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -40,7 +41,7 @@ OAuth2UserService oidcUserService(AadAuthenticationPr @EnableWebSecurity @EnableMethodSecurity - @ConditionalOnMissingBean(SecurityFilterChain.class) + @ConditionalOnDefaultWebSecurity @ConditionalOnExpression("!'${spring.cloud.azure.active-directory.application-type}'.equalsIgnoreCase('web_application_and_resource_server')") static class DefaultAadWebSecurityConfiguration { diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfigurationTests.java index 21564a55d17f..6b42d5fd24b0 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfigurationTests.java @@ -9,7 +9,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.logging.LogLevel; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -34,6 +36,7 @@ import java.util.Map; import static com.azure.spring.cloud.autoconfigure.implementation.aad.WebApplicationContextRunnerUtils.resourceServerContextRunner; +import static com.azure.spring.cloud.autoconfigure.implementation.aad.WebApplicationContextRunnerUtils.resourceServerRunner; import static com.azure.spring.cloud.autoconfigure.implementation.aad.WebApplicationContextRunnerUtils.withResourceServerPropertyValues; import static com.azure.spring.cloud.autoconfigure.implementation.aad.security.AadResourceServerHttpSecurityConfigurer.aadResourceServer; import static org.assertj.core.api.Assertions.assertThat; @@ -145,6 +148,38 @@ void useCustomJwtGrantedAuthoritiesConverter() { }); } + @Test + void useDefaultWebSecurityConfigurerAdapter() { + resourceServerRunner() + .withPropertyValues("spring.cloud.azure.active-directory.enabled=true", + "spring.cloud.azure.active-directory.credential.client-id=fake-client-id" + ) + .run(context -> { + assertThat(context).hasSingleBean(SecurityFilterChain.class); + assertThat(context).hasBean("defaultAadResourceServerFilterChain"); + }); + } + + @Test + void useCustomSecurityFilterChain() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + HttpMessageConvertersAutoConfiguration.class, + RestTemplateAutoConfiguration.class)) + .withUserConfiguration(AzureGlobalPropertiesAutoConfiguration.class, + TestAadResourceServerConfiguration.class, + AadAutoConfiguration.class) + .withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO)) + .withClassLoader(new FilteredClassLoader(ClientRegistration.class)) + .withPropertyValues("spring.cloud.azure.active-directory.enabled=true", + "spring.cloud.azure.active-directory.credential.client-id=fake-client-id" + ) + .run(context -> { + assertThat(context).hasSingleBean(SecurityFilterChain.class); + assertThat(context).hasBean("testAadResourceServerFilterChain"); + }); + } + @EnableWebSecurity @EnableMethodSecurity static class TestAadResourceServerConfiguration { diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfigurationTests.java new file mode 100644 index 000000000000..2d33ab505ac2 --- /dev/null +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadWebApplicationConfigurationTests.java @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.spring.cloud.autoconfigure.implementation.aad.configuration; + +import com.azure.spring.cloud.autoconfigure.implementation.context.AzureGlobalPropertiesAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +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.web.SecurityFilterChain; + +import static com.azure.spring.cloud.autoconfigure.implementation.aad.WebApplicationContextRunnerUtils.webApplicationContextRunner; +import static org.assertj.core.api.Assertions.assertThat; + +class AadWebApplicationConfigurationTests { + @Test + void useDefaultSecurityFilterChain() { + webApplicationContextRunner() + .withPropertyValues("spring.cloud.azure.active-directory.enabled=true", + "spring.cloud.azure.active-directory.credential.client-id=fake-client-id" + ) + .run(context -> { + assertThat(context).hasSingleBean(SecurityFilterChain.class); + assertThat(context).hasBean("defaultAadWebApplicationFilterChain"); + }); + } + + @Test + void useCustomSecurityFilterChain() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + HttpMessageConvertersAutoConfiguration.class, + RestTemplateAutoConfiguration.class)) + .withUserConfiguration(AzureGlobalPropertiesAutoConfiguration.class, + TestSecurityFilterChain.class, + AadAutoConfiguration.class) + .withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO)) + .withPropertyValues("spring.cloud.azure.active-directory.enabled=true", + "spring.cloud.azure.active-directory.credential.client-id=fake-client-id" + ) + .run(context -> { + assertThat(context).hasSingleBean(SecurityFilterChain.class); + assertThat(context).hasBean("testSecurityFilterChain"); + }); + } + + @EnableWebSecurity + static class TestSecurityFilterChain { + + @Bean + public SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { + return http.oauth2Login(Customizer.withDefaults()).authorizeRequests(request -> request.anyRequest().authenticated()).build(); + } + } +}