Updates spring-vault to 4.0.0-SNAPSHOT

Removes references to removed classes from spring-vault
This commit is contained in:
spencergibb
2025-06-06 13:42:08 -04:00
parent d79a72c878
commit d5fef77366
8 changed files with 7 additions and 421 deletions

View File

@@ -20,14 +20,12 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.system.SystemProperties;
import org.springframework.cloud.vault.config.VaultProperties.AppRoleProperties;
import org.springframework.cloud.vault.config.VaultProperties.AwsIamProperties;
@@ -35,9 +33,6 @@ import org.springframework.cloud.vault.config.VaultProperties.AzureMsiProperties
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.vault.authentication.AppIdAuthentication;
import org.springframework.vault.authentication.AppIdAuthenticationOptions;
import org.springframework.vault.authentication.AppIdUserIdMechanism;
import org.springframework.vault.authentication.AppRoleAuthentication;
import org.springframework.vault.authentication.AppRoleAuthenticationOptions;
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.AppRoleAuthenticationOptionsBuilder;
@@ -59,15 +54,12 @@ import org.springframework.vault.authentication.CubbyholeAuthenticationOptions;
import org.springframework.vault.authentication.GcpComputeAuthentication;
import org.springframework.vault.authentication.GcpComputeAuthenticationOptions;
import org.springframework.vault.authentication.GcpComputeAuthenticationOptions.GcpComputeAuthenticationOptionsBuilder;
import org.springframework.vault.authentication.IpAddressUserId;
import org.springframework.vault.authentication.KubernetesAuthentication;
import org.springframework.vault.authentication.KubernetesAuthenticationOptions;
import org.springframework.vault.authentication.KubernetesServiceAccountTokenFile;
import org.springframework.vault.authentication.MacAddressUserId;
import org.springframework.vault.authentication.PcfAuthentication;
import org.springframework.vault.authentication.PcfAuthenticationOptions;
import org.springframework.vault.authentication.ResourceCredentialSupplier;
import org.springframework.vault.authentication.StaticUserId;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.RestOperations;
@@ -113,9 +105,6 @@ class ClientAuthenticationFactory {
switch (this.vaultProperties.getAuthentication()) {
case APPID:
return appIdAuthentication(this.vaultProperties);
case APPROLE:
return appRoleAuthentication(this.vaultProperties);
@@ -137,9 +126,6 @@ class ClientAuthenticationFactory {
case GCP_GCE:
return gcpGceAuthentication(this.vaultProperties);
case GCP_IAM:
return gcpIamAuthentication(this.vaultProperties);
case KUBERNETES:
return kubernetesAuthentication(this.vaultProperties);
@@ -154,51 +140,6 @@ class ClientAuthenticationFactory {
String.format("Client authentication %s not supported", this.vaultProperties.getAuthentication()));
}
private ClientAuthentication appIdAuthentication(VaultProperties vaultProperties) {
VaultProperties.AppIdProperties appId = vaultProperties.getAppId();
Assert.hasText(appId.getUserId(), "UserId (spring.cloud.vault.app-id.user-id) must not be empty");
AppIdAuthenticationOptions authenticationOptions = AppIdAuthenticationOptions.builder()
.appId(vaultProperties.getApplicationName()) //
.path(appId.getAppIdPath()) //
.userIdMechanism(getAppIdMechanism(appId))
.build();
return new AppIdAuthentication(authenticationOptions, this.restOperations);
}
private AppIdUserIdMechanism getAppIdMechanism(VaultProperties.AppIdProperties appId) {
try {
Class<?> userIdClass = ClassUtils.forName(appId.getUserId(), null);
return (AppIdUserIdMechanism) BeanUtils.instantiateClass(userIdClass);
}
catch (ClassNotFoundException ex) {
switch (appId.getUserId().toUpperCase(Locale.ROOT)) {
case VaultProperties.AppIdProperties.IP_ADDRESS:
return new IpAddressUserId();
case VaultProperties.AppIdProperties.MAC_ADDRESS:
if (StringUtils.hasText(appId.getNetworkInterface())) {
try {
return new MacAddressUserId(Integer.parseInt(appId.getNetworkInterface()));
}
catch (NumberFormatException e) {
return new MacAddressUserId(appId.getNetworkInterface());
}
}
return new MacAddressUserId();
default:
return new StaticUserId(appId.getUserId());
}
}
}
private ClientAuthentication appRoleAuthentication(VaultProperties vaultProperties) {
AppRoleAuthenticationOptions options = getAppRoleAuthenticationOptions(vaultProperties);
@@ -354,20 +295,6 @@ class ClientAuthenticationFactory {
return new GcpComputeAuthentication(builder.build(), this.restOperations, this.externalRestOperations);
}
private ClientAuthentication gcpIamAuthentication(VaultProperties vaultProperties) {
if (googleCredentialPresent) {
return GcpIamAuthenticationFactory.create(vaultProperties, this.restOperations);
}
if (googleCredentialsPresent) {
return GcpIamCredentialsAuthenticationFactory.create(vaultProperties, this.restOperations);
}
throw new IllegalStateException(
"Cannot create authentication mechanism for GCP IAM. This method requires one of the following dependencies: google-auth-library-oauth2-http or google-api-client (deprecated).");
}
private ClientAuthentication kubernetesAuthentication(VaultProperties vaultProperties) {
VaultProperties.KubernetesProperties kubernetes = vaultProperties.getKubernetes();

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2020-2021 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.cloud.vault.config;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Base64;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import org.springframework.cloud.vault.config.VaultProperties.GcpIamProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.authentication.GcpCredentialSupplier;
import org.springframework.vault.authentication.GcpIamAuthentication;
import org.springframework.vault.authentication.GcpIamAuthenticationOptions;
import org.springframework.vault.authentication.GcpIamAuthenticationOptions.GcpIamAuthenticationOptionsBuilder;
import org.springframework.web.client.RestOperations;
/**
* Utility to create {@link GcpIamAuthentication} for the IAM authentication method.
*
* @author Mark Paluch
* @since 3.0.2
*/
final class GcpIamAuthenticationFactory {
private GcpIamAuthenticationFactory() {
}
static ClientAuthentication create(VaultProperties vaultProperties, RestOperations restOperations) {
VaultProperties.GcpIamProperties gcp = vaultProperties.getGcpIam();
Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-iam.role) must not be empty");
GcpIamAuthenticationOptionsBuilder builder = GcpIamAuthenticationOptions.builder()
.path(gcp.getGcpPath())
.role(gcp.getRole())
.jwtValidity(gcp.getJwtValidity());
if (StringUtils.hasText(gcp.getProjectId())) {
builder.projectId(gcp.getProjectId());
}
if (StringUtils.hasText(gcp.getServiceAccountId())) {
builder.serviceAccountId(gcp.getServiceAccountId());
}
GcpCredentialSupplier supplier = () -> getGoogleCredential(gcp);
builder.credential(supplier.get());
GcpIamAuthenticationOptions options = builder.build();
return new GcpIamAuthentication(options, restOperations);
}
private static GoogleCredential getGoogleCredential(GcpIamProperties gcp) throws IOException {
VaultProperties.GcpCredentials credentialProperties = gcp.getCredentials();
if (credentialProperties.getLocation() != null) {
return GoogleCredential.fromStream(credentialProperties.getLocation().getInputStream());
}
if (StringUtils.hasText(credentialProperties.getEncodedKey())) {
return GoogleCredential
.fromStream(new ByteArrayInputStream(Base64.getDecoder().decode(credentialProperties.getEncodedKey())));
}
return GoogleCredential.getApplicationDefault();
}
}

View File

@@ -371,7 +371,7 @@ public class VaultProperties implements EnvironmentAware {
*/
public enum AuthenticationMethod {
APPID, APPROLE, AWS_EC2, AWS_IAM, AZURE_MSI, CERT, CUBBYHOLE, GCP_GCE, GCP_IAM, KUBERNETES, NONE, PCF, TOKEN;
APPROLE, AWS_EC2, AWS_IAM, AZURE_MSI, CERT, CUBBYHOLE, GCP_GCE, KUBERNETES, NONE, PCF, TOKEN;
}

View File

@@ -72,8 +72,11 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
protected Mono<Health> doHealthCheck(Builder builder) {
return this.vaultOperations
.doWithVault((it) -> it.get().uri("sys/health").header(VaultHttpHeaders.VAULT_NAMESPACE, "").exchange())
.flatMap((it) -> it.bodyToMono(VaultHealthImpl.class))
.doWithVault((it) -> it.get()
.uri("sys/health")
.header(VaultHttpHeaders.VAULT_NAMESPACE, "")
.retrieve()
.bodyToMono(VaultHealthImpl.class))
.onErrorResume(WebClientResponseException.class, VaultReactiveHealthIndicator::deserializeError)
.map((vaultHealthResponse) -> getHealth(builder, vaultHealthResponse));
}

View File

@@ -1,141 +0,0 @@
/*
* Copyright 2016-2021 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.cloud.vault.config;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.vault.util.Settings;
import org.springframework.cloud.vault.util.TestRestTemplateFactory;
import org.springframework.cloud.vault.util.VaultRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.vault.authentication.AppIdAuthentication;
import org.springframework.vault.authentication.AppIdAuthenticationOptions;
import org.springframework.vault.authentication.AppIdUserIdMechanism;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.core.VaultOperations;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Mark Paluch
*/
@SpringBootTest(classes = { VaultConfigAppIdCustomMechanismTests.TestApplication.class },
properties = { "spring.cloud.vault.authentication=appid",
"VaultConfigAppIdCustomMechanismTests.custom.config=true",
"spring.cloud.vault.applicationName=VaultConfigAppIdCustomMechanismTests",
"spring.main.allow-bean-definition-overriding=true", "spring.cloud.bootstrap.enabled=true" })
public class VaultConfigAppIdCustomMechanismTests {
@Value("${vault.value}")
String configValue;
@BeforeAll
public static void beforeClass() {
VaultRule vaultRule = new VaultRule();
vaultRule.before();
VaultProperties vaultProperties = Settings.createVaultProperties();
vaultProperties.setAuthentication(VaultProperties.AuthenticationMethod.APPID);
if (!vaultRule.prepare().hasAuth(vaultProperties.getAppId().getAppIdPath())) {
vaultRule.prepare().mountAuth(vaultProperties.getAppId().getAppIdPath());
}
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
String rules = "{ \"name\": \"testpolicy\",\n" //
+ " \"path\": {\n" //
+ " \"*\": { \"policy\": \"read\" }\n" //
+ " }\n" //
+ "}";
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
String appId = VaultConfigAppIdCustomMechanismTests.class.getSimpleName();
vaultOperations.write("secret/" + appId, Collections.singletonMap("vault.value", appId));
Map<String, String> appIdData = new HashMap<>();
appIdData.put("value", "testpolicy"); // policy
appIdData.put("display_name", "this is my test application");
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData);
Map<String, String> userIdData = new HashMap<>();
userIdData.put("value", appId); // name of the app-id
userIdData.put("cidr_block", "0.0.0.0/0");
String userId = new StaticUserIdMechanism().createUserId();
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData);
}
@Test
public void contextLoads() {
assertThat(this.configValue).isEqualTo(getClass().getSimpleName());
}
@SpringBootApplication
public static class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
@Configuration(proxyBeanMethods = false)
public static class BootstrapConfiguration {
@ConditionalOnProperty("VaultConfigAppIdCustomMechanismTests.custom.config")
@Bean
ClientAuthentication clientAuthentication() {
RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration());
return new AppIdAuthentication(AppIdAuthenticationOptions.builder()
.appId(VaultConfigAppIdCustomMechanismTests.class.getSimpleName())
.userIdMechanism(new StaticUserIdMechanism())
.build(), restTemplate);
}
}
public static class StaticUserIdMechanism implements AppIdUserIdMechanism {
@Override
public String createUserId() {
return "static-string";
}
}
}

View File

@@ -1,114 +0,0 @@
/*
* Copyright 2016-2021 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.cloud.vault.config;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.vault.util.Settings;
import org.springframework.cloud.vault.util.VaultRule;
import org.springframework.vault.authentication.IpAddressUserId;
import org.springframework.vault.core.VaultOperations;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration test using config infrastructure with AppId authentication.
*
* <p>
* In case this test should fail because of SSL make sure you run the test within the
* spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is
* referenced with {@code ../work/keystore.jks}.
*
* @author Mark Paluch
*/
@SpringBootTest(classes = VaultConfigAppIdTests.TestApplication.class,
properties = { "spring.cloud.vault.authentication=appid", "spring.cloud.vault.app-id.user-id=IP_ADDRESS",
"spring.cloud.vault.application-name=VaultConfigAppIdTests", "spring.cloud.bootstrap.enabled=true" })
public class VaultConfigAppIdTests {
@Value("${vault.value}")
String configValue;
@BeforeAll
public static void beforeClass() {
VaultRule vaultRule = new VaultRule();
vaultRule.before();
VaultProperties vaultProperties = Settings.createVaultProperties();
vaultProperties.setAuthentication(VaultProperties.AuthenticationMethod.APPID);
vaultProperties.getAppId().setUserId(VaultProperties.AppIdProperties.IP_ADDRESS);
if (!vaultRule.prepare().hasAuth(vaultProperties.getAppId().getAppIdPath())) {
vaultRule.prepare().mountAuth(vaultProperties.getAppId().getAppIdPath());
}
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
String rules = "{ \"name\": \"testpolicy\",\n" //
+ " \"path\": {\n" //
+ " \"*\": { \"policy\": \"read\" }\n" //
+ " }\n" //
+ "}";
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
String appId = VaultConfigAppIdTests.class.getSimpleName();
vaultOperations.write("secret/" + VaultConfigAppIdTests.class.getSimpleName(),
Collections.singletonMap("vault.value", "foo"));
Map<String, String> appIdData = new HashMap<>();
appIdData.put("value", "testpolicy"); // policy
appIdData.put("display_name", "this is my test application");
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData);
Map<String, String> userIdData = new HashMap<>();
userIdData.put("value", appId); // name of the app-id
userIdData.put("cidr_block", "0.0.0.0/0");
String userId = new IpAddressUserId().createUserId();
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData);
}
@Test
public void contextLoads() {
assertThat(this.configValue).isEqualTo("foo");
}
@SpringBootApplication
public static class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
}

View File

@@ -1,4 +1,3 @@
# Bootstrap Configuration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.vault.config.VaultConfigAppIdCustomMechanismTests.BootstrapConfiguration,\
org.springframework.cloud.vault.config.VaultConfigWithVaultConfigurerTests.ConfigurerBootstrapApplication

View File

@@ -20,7 +20,7 @@
<description>Spring Cloud Vault Dependencies</description>
<properties>
<spring-vault.version>3.2.0</spring-vault.version>
<spring-vault.version>4.0.0-SNAPSHOT</spring-vault.version>
</properties>
<dependencyManagement>