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:
Darren Forsythe 2018-12-18 01:11:12 +00:00 коммит произвёл weiping
Родитель f36ac06d52
Коммит 03825fe895
8 изменённых файлов: 104 добавлений и 71 удалений

Просмотреть файл

@ -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();