Cannot override ServiceEndpoint Properties (#503)
Remove Yml YamlFileApplicationContextInitializer. Remap yml to properties file. Add PropertySource to ADD Autoconfiguration. Use BeanDefinition constants for scope. Add tests to verify expected behavior
This commit is contained in:
Родитель
f36ac06d52
Коммит
03825fe895
|
@ -11,12 +11,14 @@ import com.nimbusds.jose.util.DefaultResourceRetriever;
|
|||
import com.nimbusds.jose.util.ResourceRetriever;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
@ -26,6 +28,7 @@ import java.util.HashMap;
|
|||
@ConditionalOnWebApplication
|
||||
@ConditionalOnProperty(prefix = "azure.activedirectory", value = {"client-id", "client-secret"})
|
||||
@EnableConfigurationProperties({AADAuthenticationProperties.class, ServiceEndpointsProperties.class})
|
||||
@PropertySource(value = "classpath:serviceEndpoints.properties")
|
||||
public class AADAuthenticationFilterAutoConfiguration {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AADAuthenticationProperties.class);
|
||||
|
||||
|
@ -47,7 +50,7 @@ public class AADAuthenticationFilterAutoConfiguration {
|
|||
* @return AADAuthenticationFilter bean
|
||||
*/
|
||||
@Bean
|
||||
@Scope("singleton")
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
@ConditionalOnMissingBean(AADAuthenticationFilter.class)
|
||||
public AADAuthenticationFilter azureADJwtTokenFilter() {
|
||||
LOG.info("AzureADJwtTokenFilter Constructor.");
|
||||
|
@ -56,7 +59,7 @@ public class AADAuthenticationFilterAutoConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@Scope("singleton")
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
@ConditionalOnMissingBean(ResourceRetriever.class)
|
||||
public ResourceRetriever getJWTResourceRetriever() {
|
||||
return new DefaultResourceRetriever(aadAuthProps.getJwtConnectTimeout(), aadAuthProps.getJwtReadTimeout(),
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
|||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnProperty(prefix = "azure.activedirectory", value = "tenant-id")
|
||||
@PropertySource("classpath:/aad-oauth2-common.properties")
|
||||
@PropertySource(value = "classpath:serviceEndpoints.properties")
|
||||
@EnableConfigurationProperties({AADAuthenticationProperties.class, ServiceEndpointsProperties.class})
|
||||
public class AADOAuth2AutoConfiguration {
|
||||
private AADAuthenticationProperties aadAuthProps;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for
|
||||
* license information.
|
||||
*/
|
||||
package com.microsoft.azure.spring.autoconfigure.aad;
|
||||
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Yaml file initializer to load the specified yaml configuration file,
|
||||
* by default the Spring will load the application.yml file.
|
||||
* <p>
|
||||
* In order to avoid possible overwritten by users' default yaml configuration file.
|
||||
*/
|
||||
public class YamlFileApplicationContextInitializer
|
||||
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||
|
||||
private static final String SERVICE_ENDPOINTS_YAML = "classpath:serviceEndpoints.yml";
|
||||
|
||||
private List<PropertySource<?>> yamlPropertySourceLoad(ConfigurableApplicationContext context) {
|
||||
final List<PropertySource<?>> serviceEndpoints;
|
||||
final Resource resource = context.getResource(SERVICE_ENDPOINTS_YAML);
|
||||
final YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
|
||||
|
||||
try {
|
||||
serviceEndpoints = sourceLoader.load("serviceEndpoints", resource);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Cannot load the azure service endpoints configuration", e);
|
||||
}
|
||||
|
||||
if (serviceEndpoints.size() != 1) {
|
||||
throw new IllegalStateException("There must be only 1 azure service endpoints configuration in classpath");
|
||||
}
|
||||
|
||||
return serviceEndpoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
final List<PropertySource<?>> serviceEndpoints = yamlPropertySourceLoad(applicationContext);
|
||||
|
||||
applicationContext.getEnvironment().getPropertySources().addFirst(serviceEndpoints.get(0));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
org.springframework.boot.env.EnvironmentPostProcessor=com.microsoft.azure.spring.cloundfoundry.environment.VcapProcessor,\
|
||||
com.microsoft.azure.keyvault.spring.KeyVaultEnvironmentPostProcessor,\
|
||||
com.microsoft.azure.spring.autoconfigure.sqlserver.AlwaysEncryptedEnvironmentPostProcessor
|
||||
org.springframework.context.ApplicationContextInitializer=\
|
||||
com.microsoft.azure.spring.autoconfigure.aad.YamlFileApplicationContextInitializer
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.microsoft.azure.spring.autoconfigure.cosmosdb.DocumentDBAutoConfiguration,\
|
||||
com.microsoft.azure.spring.autoconfigure.cosmosdb.DocumentDbRepositoriesAutoConfiguration,\
|
||||
com.microsoft.azure.spring.autoconfigure.gremlin.GremlinAutoConfiguration,\
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
azure.service.endpoints.cn.aadSigninUri=https://login.partner.microsoftonline.cn/
|
||||
azure.service.endpoints.cn.aadGraphApiUri=https://graph.chinacloudapi.cn/
|
||||
azure.service.endpoints.cn.aadKeyDiscoveryUri=https://login.partner.microsoftonline.cn/common/discovery/keys
|
||||
azure.service.endpoints.cn.aadMembershipRestUri=https://graph.chinacloudapi.cn/me/memberOf?api-version=1.6
|
||||
azure.service.endpoints.global.aadSigninUri=https://login.microsoftonline.com/
|
||||
azure.service.endpoints.global.aadGraphApiUri=https://graph.windows.net/
|
||||
azure.service.endpoints.global.aadKeyDiscoveryUri=https://login.microsoftonline.com/common/discovery/keys/
|
||||
azure.service.endpoints.global.aadMembershipRestUri=https://graph.windows.net/me/memberOf?api-version=1.6
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
azure:
|
||||
service:
|
||||
endpoints:
|
||||
cn:
|
||||
aadSigninUri: https://login.partner.microsoftonline.cn/
|
||||
aadGraphApiUri: https://graph.chinacloudapi.cn/
|
||||
aadKeyDiscoveryUri: https://login.partner.microsoftonline.cn/common/discovery/keys
|
||||
aadMembershipRestUri: https://graph.chinacloudapi.cn/me/memberOf?api-version=1.6
|
||||
global:
|
||||
aadSigninUri: https://login.microsoftonline.com/
|
||||
aadGraphApiUri: https://graph.windows.net/
|
||||
aadKeyDiscoveryUri: https://login.microsoftonline.com/common/discovery/keys
|
||||
aadMembershipRestUri: https://graph.windows.net/me/memberOf?api-version=1.6
|
|
@ -8,6 +8,10 @@ package com.microsoft.azure.spring.autoconfigure.aad;
|
|||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AADAuthenticationAutoConfigurationTest {
|
||||
|
@ -26,4 +30,41 @@ public class AADAuthenticationAutoConfigurationTest {
|
|||
assertThat(azureADJwtTokenFilter).isExactlyInstanceOf(AADAuthenticationFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceEndpointsCanBeOverriden() {
|
||||
this.contextRunner.withPropertyValues("azure.service.endpoints.global.aadKeyDiscoveryUri=https://test/",
|
||||
"azure.service.endpoints.global.aadSigninUri=https://test/",
|
||||
"azure.service.endpoints.global.aadGraphApiUri=https://test/",
|
||||
"azure.service.endpoints.global.aadKeyDiscoveryUri=https://test/",
|
||||
"azure.service.endpoints.global.aadMembershipRestUri=https://test/")
|
||||
.run(context -> {
|
||||
final Environment environment = context.getEnvironment();
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadSigninUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadGraphApiUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadKeyDiscoveryUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadMembershipRestUri"))
|
||||
.isEqualTo("https://test/");
|
||||
final ServiceEndpointsProperties serviceEndpointsProperties =
|
||||
context.getBean(ServiceEndpointsProperties.class);
|
||||
assertThat(serviceEndpointsProperties)
|
||||
.isNotNull().extracting(ServiceEndpointsProperties::getEndpoints).isNotEmpty();
|
||||
final Map<String, ServiceEndpoints> endpoints = serviceEndpointsProperties.getEndpoints();
|
||||
assertThat(endpoints).hasSize(2);
|
||||
assertThat(endpoints.get("cn")).isNotNull()
|
||||
.extracting(ServiceEndpoints::getAadGraphApiUri, ServiceEndpoints::getAadKeyDiscoveryUri,
|
||||
ServiceEndpoints::getAadMembershipRestUri, ServiceEndpoints::getAadSigninUri)
|
||||
.containsExactly("https://graph.chinacloudapi.cn/",
|
||||
"https://login.partner.microsoftonline.cn/common/discovery/keys",
|
||||
"https://graph.chinacloudapi.cn/me/memberOf?api-version=1.6",
|
||||
"https://login.partner.microsoftonline.cn/");
|
||||
assertThat(endpoints.get("global")).isNotNull()
|
||||
.extracting(ServiceEndpoints::getAadGraphApiUri, ServiceEndpoints::getAadKeyDiscoveryUri,
|
||||
ServiceEndpoints::getAadMembershipRestUri, ServiceEndpoints::getAadSigninUri)
|
||||
.containsExactly("https://test/", "https://test/", "https://test/", "https://test/");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,18 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePropertySource;
|
||||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AADOAuth2ConfigTest {
|
||||
private static final String AAD_OAUTH2_MINIMUM_PROPS = "aad-backend-oauth2-minimum.properties";
|
||||
private Resource testResource;
|
||||
|
@ -66,10 +72,51 @@ public class AADOAuth2ConfigTest {
|
|||
testContext.getBean(OAuth2UserService.class);
|
||||
}
|
||||
|
||||
private AnnotationConfigWebApplicationContext initTestContext() {
|
||||
@Test
|
||||
public void testEndpointsPropertiesLoadAndOverridable() {
|
||||
testContext = initTestContext("azure.service.endpoints.global.aadKeyDiscoveryUri=https://test/",
|
||||
"azure.service.endpoints.global.aadSigninUri=https://test/",
|
||||
"azure.service.endpoints.global.aadGraphApiUri=https://test/",
|
||||
"azure.service.endpoints.global.aadKeyDiscoveryUri=https://test/",
|
||||
"azure.service.endpoints.global.aadMembershipRestUri=https://test/");
|
||||
|
||||
|
||||
final Environment environment = testContext.getEnvironment();
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadSigninUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadGraphApiUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadKeyDiscoveryUri"))
|
||||
.isEqualTo("https://test/");
|
||||
assertThat(environment.getProperty("azure.service.endpoints.global.aadMembershipRestUri"))
|
||||
.isEqualTo("https://test/");
|
||||
final ServiceEndpointsProperties serviceEndpointsProperties =
|
||||
testContext.getBean(ServiceEndpointsProperties.class);
|
||||
assertThat(serviceEndpointsProperties)
|
||||
.isNotNull().extracting(ServiceEndpointsProperties::getEndpoints).isNotEmpty();
|
||||
final Map<String, ServiceEndpoints> endpoints = serviceEndpointsProperties.getEndpoints();
|
||||
assertThat(endpoints).hasSize(2);
|
||||
assertThat(endpoints.get("cn")).isNotNull()
|
||||
.extracting(ServiceEndpoints::getAadGraphApiUri, ServiceEndpoints::getAadKeyDiscoveryUri,
|
||||
ServiceEndpoints::getAadMembershipRestUri, ServiceEndpoints::getAadSigninUri)
|
||||
.containsExactly("https://graph.chinacloudapi.cn/",
|
||||
"https://login.partner.microsoftonline.cn/common/discovery/keys",
|
||||
"https://graph.chinacloudapi.cn/me/memberOf?api-version=1.6",
|
||||
"https://login.partner.microsoftonline.cn/");
|
||||
assertThat(endpoints.get("global")).isNotNull()
|
||||
.extracting(ServiceEndpoints::getAadGraphApiUri, ServiceEndpoints::getAadKeyDiscoveryUri,
|
||||
ServiceEndpoints::getAadMembershipRestUri, ServiceEndpoints::getAadSigninUri)
|
||||
.containsExactly("https://test/", "https://test/", "https://test/", "https://test/");
|
||||
|
||||
}
|
||||
|
||||
private AnnotationConfigWebApplicationContext initTestContext(String... environment) {
|
||||
final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
|
||||
context.getEnvironment().getPropertySources().addLast(testPropResource);
|
||||
if (environment.length > 0) {
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, environment);
|
||||
}
|
||||
context.register(AADOAuth2AutoConfiguration.class);
|
||||
context.refresh();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче