From 5fef3ca6365a16bf7037a2e9f3453b5d2a3126a5 Mon Sep 17 00:00:00 2001 From: Kaveh Shamsi Date: Fri, 19 Apr 2024 13:11:11 +0200 Subject: [PATCH] always registers the client RestTemplate, even if oauth2 properties are missing (#414) * Bumps Spring Boot version to 3.2.5 * Some code cleanup * Registers the client RestTemplate, even if oauth2 properties are missing Signed-off-by: kvmw --- gradle.properties | 2 +- ... => OAuth2ConfigDataLocationResolver.java} | 59 ++++++++++--------- .../VaultTokenRenewalAutoConfiguration.java | 15 ++--- .../main/resources/META-INF/spring.factories | 2 +- 4 files changed, 38 insertions(+), 40 deletions(-) rename spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/{ConfigClientOAuth2ConfigDataLocationResolver.java => OAuth2ConfigDataLocationResolver.java} (73%) diff --git a/gradle.properties b/gradle.properties index 9144557..d96c3f8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ version=4.1.2-SNAPSHOT parallel=true springCloudVersion=2023.0.1 -springBootVersion=3.2.4 +springBootVersion=3.2.5 javaCfenvVersion=3.1.5 nohttpVersion=0.0.11 wireMockVersion=3.5.2 diff --git a/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/ConfigClientOAuth2ConfigDataLocationResolver.java b/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/OAuth2ConfigDataLocationResolver.java similarity index 73% rename from spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/ConfigClientOAuth2ConfigDataLocationResolver.java rename to spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/OAuth2ConfigDataLocationResolver.java index d24cd78..ccd7142 100644 --- a/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/ConfigClientOAuth2ConfigDataLocationResolver.java +++ b/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/OAuth2ConfigDataLocationResolver.java @@ -16,8 +16,12 @@ package io.pivotal.spring.cloud.config.client; import org.apache.commons.logging.Log; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.context.config.*; +import org.springframework.boot.context.config.ConfigDataLocation; +import org.springframework.boot.context.config.ConfigDataLocationNotFoundException; +import org.springframework.boot.context.config.ConfigDataLocationResolver; +import org.springframework.boot.context.config.ConfigDataLocationResolverContext; +import org.springframework.boot.context.config.ConfigDataResourceNotFoundException; +import org.springframework.boot.context.config.Profiles; import org.springframework.boot.logging.DeferredLogFactory; import org.springframework.cloud.config.client.ConfigClientProperties; import org.springframework.cloud.config.client.ConfigClientRequestTemplateFactory; @@ -30,6 +34,8 @@ import java.util.List; +import static io.pivotal.spring.cloud.config.client.ConfigClientOAuth2Properties.PREFIX; + /** * Using oauth2 properties to configure an authorization interceptor for the * RestTemplate that calls config server. @@ -44,13 +50,13 @@ * {@link ConfigResourceClientAutoConfiguration} and * {@link VaultTokenRenewalAutoConfiguration} after application startup. */ -public class ConfigClientOAuth2ConfigDataLocationResolver +public class OAuth2ConfigDataLocationResolver implements ConfigDataLocationResolver, Ordered { private final Log log; - public ConfigClientOAuth2ConfigDataLocationResolver(DeferredLogFactory factory) { - this.log = factory.getLog(ConfigClientOAuth2ConfigDataLocationResolver.class); + public OAuth2ConfigDataLocationResolver(DeferredLogFactory factory) { + this.log = factory.getLog(OAuth2ConfigDataLocationResolver.class); } @Override @@ -65,34 +71,29 @@ public boolean isResolvable(ConfigDataLocationResolverContext resolverContext, C return false; } - var oAuth2Properties = binder.bind(ConfigClientOAuth2Properties.PREFIX, ConfigClientOAuth2Properties.class) - .orElse(null); - if (oAuth2Properties == null) { - log.warn("Config Client oauth2 properties are missing. Skipping the auth interceptor configuration"); - return false; - } - var bootstrapContext = resolverContext.getBootstrapContext(); - // Register the oauth2 properties - bootstrapContext.registerIfAbsent(ConfigClientOAuth2Properties.class, - BootstrapRegistry.InstanceSupplier.of(oAuth2Properties).withScope(BootstrapRegistry.Scope.PROTOTYPE)); - - // Register the custom factory with oauth2 interceptor. - bootstrapContext.registerIfAbsent(ConfigClientRequestTemplateFactory.class, - context -> new ConfigClientOAuth2RequestTemplateFactory(this.log, - context.get(ConfigClientProperties.class), oAuth2Properties)); + var oAuth2Properties = binder.bind(PREFIX, ConfigClientOAuth2Properties.class).orElse(null); + if (oAuth2Properties != null) { + // Register the custom factory with oauth2 interceptor. + bootstrapContext.registerIfAbsent(ConfigClientRequestTemplateFactory.class, + context -> new OAuth2ConfigClientRequestTemplateFactory(this.log, + context.get(ConfigClientProperties.class), oAuth2Properties)); + } + else { + log.warn("Config Client oauth2 properties are missing. Skipping the auth interceptor configuration"); + // Register the default factory. + bootstrapContext.registerIfAbsent(ConfigClientRequestTemplateFactory.class, + context -> new ConfigClientRequestTemplateFactory(this.log, + context.get(ConfigClientProperties.class))); + } bootstrapContext.addCloseListener(event -> { - var beanFactory = event.getApplicationContext().getBeanFactory(); - // Add the RestTemplate as bean, once the startup is finished. - beanFactory.registerSingleton("configClientRestTemplate", - event.getBootstrapContext().get(RestTemplate.class)); + event.getApplicationContext() + .getBeanFactory() + .registerSingleton("configClientRestTemplate", event.getBootstrapContext().get(RestTemplate.class)); - // Add the OAuth2 Properties as bean, once the startup is finished. - beanFactory.registerSingleton("configClientOAuth2Properties", - event.getBootstrapContext().get(ConfigClientOAuth2Properties.class)); }); return false; @@ -120,11 +121,11 @@ public int getOrder() { return -2; } - private static class ConfigClientOAuth2RequestTemplateFactory extends ConfigClientRequestTemplateFactory { + private static class OAuth2ConfigClientRequestTemplateFactory extends ConfigClientRequestTemplateFactory { private final ClientRegistration clientRegistration; - public ConfigClientOAuth2RequestTemplateFactory(Log log, ConfigClientProperties clientProperties, + public OAuth2ConfigClientRequestTemplateFactory(Log log, ConfigClientProperties clientProperties, ConfigClientOAuth2Properties oAuth2Properties) { super(log, clientProperties); diff --git a/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/VaultTokenRenewalAutoConfiguration.java b/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/VaultTokenRenewalAutoConfiguration.java index e48da77..866258f 100644 --- a/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/VaultTokenRenewalAutoConfiguration.java +++ b/spring-cloud-services-config-client-autoconfigure/src/main/java/io/pivotal/spring/cloud/config/client/VaultTokenRenewalAutoConfiguration.java @@ -51,7 +51,7 @@ @AutoConfiguration(after = ConfigClientAutoConfiguration.class) @ConditionalOnBean(ConfigClientProperties.class) @ConditionalOnProperty(name = "spring.cloud.config.token") -@EnableConfigurationProperties(ConfigClientOAuth2Properties.class) +@EnableConfigurationProperties @EnableScheduling public class VaultTokenRenewalAutoConfiguration { @@ -61,9 +61,6 @@ public class VaultTokenRenewalAutoConfiguration { private static final String REFRESH_PATH = "/vault/v1/auth/token/renew-self"; - @Value("${spring.cloud.config.token}") - private String vaultToken; - // Default to a 300 second (5 minute) TTL @Value("${vault.token.ttl:300000}") long ttl; @@ -75,19 +72,19 @@ public VaultTokenRefresher vaultTokenRefresher( ConfigClientProperties configClientProperties) { var refreshUri = configClientProperties.getUri()[0] + REFRESH_PATH; - var obscuredToken = this.vaultToken.substring(0, 4) + "[*]" - + this.vaultToken.substring(this.vaultToken.length() - 4); + String vaultToken = configClientProperties.getToken(); + var obscuredToken = vaultToken.substring(0, 4) + "[*]" + vaultToken.substring(vaultToken.length() - 4); return new VaultTokenRefresher(configClientRestTemplate, obscuredToken, ttl, refreshUri, - buildTokenRenewRequest()); + buildTokenRenewRequest(vaultToken)); } - private HttpEntity> buildTokenRenewRequest() { + private HttpEntity> buildTokenRenewRequest(String vaultToken) { // convert to seconds, since that's what Vault wants var ttlInSeconds = this.ttl / 1000; var requestBody = Map.of("increment", ttlInSeconds); var headers = new HttpHeaders(); - headers.set(VAULT_TOKEN_HEADER, this.vaultToken); + headers.set(VAULT_TOKEN_HEADER, vaultToken); headers.setContentType(MediaType.APPLICATION_JSON); return new HttpEntity<>(requestBody, headers); diff --git a/spring-cloud-services-config-client-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-services-config-client-autoconfigure/src/main/resources/META-INF/spring.factories index 41bd3be..8a9bb60 100644 --- a/spring-cloud-services-config-client-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-services-config-client-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,5 +1,5 @@ org.springframework.boot.context.config.ConfigDataLocationResolver=\ -io.pivotal.spring.cloud.config.client.ConfigClientOAuth2ConfigDataLocationResolver +io.pivotal.spring.cloud.config.client.OAuth2ConfigDataLocationResolver org.springframework.cloud.bootstrap.BootstrapConfiguration=\ io.pivotal.spring.cloud.config.client.ConfigClientOAuth2BootstrapConfiguration