diff --git a/docs/src/main/asciidoc/authentication.adoc b/docs/src/main/asciidoc/authentication.adoc index 3f3d9967..3579e077 100644 --- a/docs/src/main/asciidoc/authentication.adoc +++ b/docs/src/main/asciidoc/authentication.adoc @@ -339,6 +339,7 @@ spring.cloud.vault: spring.cloud.vault: authentication: AWS_IAM aws-iam: + region: aws-global role: my-dev-role aws-path: aws server-name: some.server.name @@ -346,6 +347,7 @@ spring.cloud.vault: ---- ==== +* `region` sets the name of the AWS region. If not supplied, the region will be determined by AWS defaults. * `role` sets the name of the role against which the login is being attempted. This should be bound to your IAM role. If one is not supplied then the friendly name of the current IAM user will be used as the vault role. diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java index 9cc76496..15078f85 100644 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java +++ b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java @@ -72,6 +72,7 @@ import org.springframework.vault.support.VaultToken; import org.springframework.web.client.RestOperations; import static java.nio.charset.StandardCharsets.UTF_8; +import software.amazon.awssdk.regions.Region; /** * Factory for {@link ClientAuthentication}. @@ -273,13 +274,16 @@ class ClientAuthenticationFactory { return new AwsEc2Authentication(authenticationOptions, this.restOperations, this.externalRestOperations); } - private ClientAuthentication awsIamAuthentication(VaultProperties vaultProperties) { + ClientAuthentication awsIamAuthentication(VaultProperties vaultProperties) { AwsIamProperties awsIam = vaultProperties.getAwsIam(); + AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions.builder(); AwsCredentialsProvider credentialsProvider = AwsCredentialProvider.getAwsCredentialsProvider(); - AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions.builder(); + if (StringUtils.hasText(awsIam.getRegion())) { + builder.region(Region.of(awsIam.getRegion())); + } if (StringUtils.hasText(awsIam.getRole())) { builder.role(awsIam.getRole()); diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java index 4b183408..5e123a89 100644 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java +++ b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java @@ -633,6 +633,12 @@ public class VaultProperties implements EnvironmentAware { */ private String awsPath = "aws"; + /** + * Name of the region, optional. Inferred by AWS defaults if not set. + * @since 4.0.1 + */ + private String region = ""; + /** * Name of the role, optional. Defaults to the friendly IAM name if not set. */ @@ -657,6 +663,10 @@ public class VaultProperties implements EnvironmentAware { return this.awsPath; } + public String getRegion() { + return this.region; + } + public String getRole() { return this.role; } @@ -670,6 +680,10 @@ public class VaultProperties implements EnvironmentAware { this.awsPath = awsPath; } + public void setRegion(String region) { + this.region = region; + } + public void setRole(String role) { this.role = role; } diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java index 9151fc29..c80ece70 100644 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java +++ b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java @@ -24,12 +24,14 @@ import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import org.junit.Test; - import org.springframework.boot.system.SystemProperties; import org.springframework.core.io.ClassPathResource; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.vault.authentication.AppRoleAuthenticationOptions; import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId; import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId; +import org.springframework.vault.authentication.AwsIamAuthentication; +import org.springframework.vault.authentication.AwsIamAuthenticationOptions; import org.springframework.vault.authentication.ClientAuthentication; import org.springframework.vault.authentication.ClientCertificateAuthentication; import org.springframework.vault.authentication.PcfAuthentication; @@ -37,6 +39,9 @@ import org.springframework.vault.authentication.TokenAuthentication; import org.springframework.vault.support.VaultToken; import org.springframework.web.client.RestTemplate; +import software.amazon.awssdk.core.SdkSystemSetting; +import software.amazon.awssdk.regions.Region; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -49,6 +54,31 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; */ public class ClientAuthenticationFactoryUnitTests { + @Test + public void shouldSupportAwsIam() { + + try { + System.setProperty(SdkSystemSetting.AWS_ACCESS_KEY_ID.property(), "foo"); + System.setProperty(SdkSystemSetting.AWS_SECRET_ACCESS_KEY.property(), "bar"); + + VaultProperties properties = new VaultProperties(); + properties.getAwsIam().setRegion(Region.AWS_GLOBAL.id()); + properties.getAwsIam().setRole("bar"); + + ClientAuthenticationFactory factory = new ClientAuthenticationFactory(properties, new RestTemplate(), + new RestTemplate()); + AwsIamAuthentication authentication = (AwsIamAuthentication) factory.awsIamAuthentication(properties); + AwsIamAuthenticationOptions options = (AwsIamAuthenticationOptions) ReflectionTestUtils + .getField(authentication, "options"); + + assertThat(options.getRegionProvider().getRegion()).isEqualTo(Region.AWS_GLOBAL); + } + finally { + System.getProperties().remove(SdkSystemSetting.AWS_ACCESS_KEY_ID.property()); + System.getProperties().remove(SdkSystemSetting.AWS_SECRET_ACCESS_KEY.property()); + } + } + @Test public void shouldSupportAppRoleRoleIdProvidedSecretIdProvided() {