diff --git a/spring-vault-core/pom.xml b/spring-vault-core/pom.xml index 0c33a798..6e453b1e 100644 --- a/spring-vault-core/pom.xml +++ b/spring-vault-core/pom.xml @@ -164,8 +164,8 @@ - com.amazonaws - aws-java-sdk-core + software.amazon.awssdk + auth true diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthentication.java index 87813580..a0285eda 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthentication.java @@ -21,11 +21,16 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.List; + +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.auth.signer.Aws4Signer; +import software.amazon.awssdk.auth.signer.params.Aws4SignerParams; +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.http.SdkHttpMethod; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; -import com.amazonaws.DefaultRequest; -import com.amazonaws.auth.AWS4Signer; -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.http.HttpMethodName; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.logging.Log; @@ -45,20 +50,20 @@ import org.springframework.web.client.RestOperations; /** * AWS IAM authentication using signed HTTP requests to query the current identity. *

- * AWS IAM authentication creates a {@link AWS4Signer signed} HTTP request that is + * AWS IAM authentication creates a {@link Aws4Signer signed} HTTP request that is * executed by Vault to get the identity of the signer using AWS STS * {@literal GetCallerIdentity}. A signature requires - * {@link com.amazonaws.auth.AWSCredentials} to calculate the signature. + * {@link com.amazonaws.auth.AwsCredentials} to calculate the signature. *

* This authentication requires AWS' Java SDK to sign request parameters and calculate the - * signature key. Using an appropriate {@link com.amazonaws.auth.AWSCredentialsProvider} + * signature key. Using an appropriate {@link com.amazonaws.auth.AwsCredentialsProvider} * allows authentication within AWS-EC2 instances with an assigned profile, within ECS and * Lambda instances. * * @author Mark Paluch * @since 1.1 * @see AwsIamAuthenticationOptions - * @see com.amazonaws.auth.AWSCredentialsProvider + * @see com.amazonaws.auth.AwsCredentialsProvider * @see RestOperations * @see Auth Backend: aws * (IAM) @@ -99,7 +104,7 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio /** * Creates a {@link AuthenticationSteps} for AWS-IAM authentication given * {@link AwsIamAuthenticationOptions}. The resulting {@link AuthenticationSteps} - * reuse eagerly-fetched {@link AWSCredentials} to prevent blocking I/O during + * reuse eagerly-fetched {@link AwsCredentials} to prevent blocking I/O during * authentication. * @param options must not be {@literal null}. * @return {@link AuthenticationSteps} for AWS-IAM authentication. @@ -109,13 +114,13 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio Assert.notNull(options, "AwsIamAuthenticationOptions must not be null"); - AWSCredentials credentials = options.getCredentialsProvider().getCredentials(); + AwsCredentials credentials = options.getCredentialsProvider().resolveCredentials(); return createAuthenticationSteps(options, credentials); } protected static AuthenticationSteps createAuthenticationSteps(AwsIamAuthenticationOptions options, - AWSCredentials credentials) { + AwsCredentials credentials) { return AuthenticationSteps.fromSupplier(() -> createRequestBody(options, credentials)) // .login(AuthenticationUtil.getLoginPath(options.getPath())); @@ -128,7 +133,7 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio @Override public AuthenticationSteps getAuthenticationSteps() { - return createAuthenticationSteps(this.options, this.options.getCredentialsProvider().getCredentials()); + return createAuthenticationSteps(this.options, this.options.getCredentialsProvider().resolveCredentials()); } @SuppressWarnings("unchecked") @@ -169,7 +174,7 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio * @return the map containing body key-value pairs. */ protected static Map createRequestBody(AwsIamAuthenticationOptions options) { - return createRequestBody(options, options.getCredentialsProvider().getCredentials()); + return createRequestBody(options, options.getCredentialsProvider().resolveCredentials()); } /** @@ -179,7 +184,7 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio * @return the map containing body key-value pairs. */ private static Map createRequestBody(AwsIamAuthenticationOptions options, - AWSCredentials credentials) { + AwsCredentials credentials) { Map login = new HashMap<>(); @@ -197,26 +202,25 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio return login; } - private static String getSignedHeaders(AwsIamAuthenticationOptions options, AWSCredentials credentials) { + private static String getSignedHeaders(AwsIamAuthenticationOptions options, AwsCredentials credentials) { - Map headers = createIamRequestHeaders(options); + Map> headers = createIamRequestHeaders(options); - AWS4Signer signer = new AWS4Signer(); + SdkHttpFullRequest.Builder builder = SdkHttpFullRequest.builder() + .contentStreamProvider(() -> new ByteArrayInputStream(REQUEST_BODY.getBytes())).headers(headers) + .method(SdkHttpMethod.POST).uri(options.getEndpointUri()); + SdkHttpFullRequest request = builder.build(); - DefaultRequest request = new DefaultRequest<>("sts"); - - request.setContent(new ByteArrayInputStream(REQUEST_BODY.getBytes())); - request.setHeaders(headers); - request.setHttpMethod(HttpMethodName.POST); - request.setEndpoint(options.getEndpointUri()); - - signer.setServiceName(request.getServiceName()); - signer.sign(request, credentials); + Region region = DefaultAwsRegionProviderChain.builder().build().getRegion(); + Aws4Signer signer = Aws4Signer.create(); + Aws4SignerParams signerParams = Aws4SignerParams.builder().awsCredentials(credentials).signingName("sts") + .signingRegion(region).build(); + SdkHttpFullRequest signedRequest = signer.sign(request, signerParams); Map map = new LinkedHashMap<>(); - for (Entry entry : request.getHeaders().entrySet()) { - map.put(entry.getKey(), Collections.singletonList(entry.getValue())); + for (Entry> entry : signedRequest.headers().entrySet()) { + map.put(entry.getKey(), entry.getValue()); } try { @@ -227,15 +231,15 @@ public class AwsIamAuthentication implements ClientAuthentication, Authenticatio } } - private static Map createIamRequestHeaders(AwsIamAuthenticationOptions options) { + private static Map> createIamRequestHeaders(AwsIamAuthenticationOptions options) { - Map headers = new LinkedHashMap<>(); + Map> headers = new LinkedHashMap<>(); - headers.put(HttpHeaders.CONTENT_LENGTH, "" + REQUEST_BODY.length()); - headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + headers.put(HttpHeaders.CONTENT_LENGTH, Collections.singletonList("" + REQUEST_BODY.length())); + headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED_VALUE)); if (StringUtils.hasText(options.getServerId())) { - headers.put("X-Vault-AWS-IAM-Server-ID", options.getServerId()); + headers.put("X-Vault-AWS-IAM-Server-ID", Collections.singletonList(options.getServerId())); } return headers; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthenticationOptions.java index a33fcc0a..7da8d7cd 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthenticationOptions.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsIamAuthenticationOptions.java @@ -17,9 +17,9 @@ package org.springframework.vault.authentication; import java.net.URI; -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.auth.AWSCredentialsProvider; -import com.amazonaws.auth.AWSStaticCredentialsProvider; +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -27,7 +27,7 @@ import org.springframework.util.Assert; /** * Authentication options for {@link AwsIamAuthentication}. *

- * Authentication options provide the path, a {@link AWSCredentialsProvider} optional role + * Authentication options provide the path, a {@link AwsCredentialsProvider} optional role * and server name ({@literal Vault-AWS-IAM-Server-ID} header). * {@link AwsIamAuthenticationOptions} can be constructed using {@link #builder()}. * Instances of this class are immutable once constructed. @@ -49,7 +49,7 @@ public class AwsIamAuthenticationOptions { /** * Credential provider. */ - private final AWSCredentialsProvider credentialsProvider; + private final AwsCredentialsProvider credentialsProvider; /** * Name of the role against which the login is being attempted. If role is not @@ -71,7 +71,7 @@ public class AwsIamAuthenticationOptions { */ private final URI endpointUri; - private AwsIamAuthenticationOptions(String path, AWSCredentialsProvider credentialsProvider, @Nullable String role, + private AwsIamAuthenticationOptions(String path, AwsCredentialsProvider credentialsProvider, @Nullable String role, @Nullable String serverId, URI endpointUri) { this.path = path; @@ -98,7 +98,7 @@ public class AwsIamAuthenticationOptions { /** * @return the credentials provider to obtain AWS credentials. */ - public AWSCredentialsProvider getCredentialsProvider() { + public AwsCredentialsProvider getCredentialsProvider() { return this.credentialsProvider; } @@ -147,7 +147,7 @@ public class AwsIamAuthenticationOptions { private String path = DEFAULT_AWS_AUTHENTICATION_PATH; @Nullable - private AWSCredentialsProvider credentialsProvider; + private AwsCredentialsProvider credentialsProvider; @Nullable private String role; @@ -176,29 +176,29 @@ public class AwsIamAuthenticationOptions { /** * Configure static AWS credentials, required to calculate the signature. Either * use static credentials or provide a - * {@link #credentialsProvider(AWSCredentialsProvider) credentials provider}. + * {@link #credentialsProvider(AwsCredentialsProvider) credentials provider}. * @param credentials must not be {@literal null}. * @return {@code this} {@link AwsIamAuthenticationOptionsBuilder}. - * @see #credentialsProvider(AWSCredentialsProvider) + * @see #credentialsProvider(AwsCredentialsProvider) */ - public AwsIamAuthenticationOptionsBuilder credentials(AWSCredentials credentials) { + public AwsIamAuthenticationOptionsBuilder credentials(AwsCredentials credentials) { Assert.notNull(credentials, "Credentials must not be null"); - return credentialsProvider(new AWSStaticCredentialsProvider(credentials)); + return credentialsProvider(StaticCredentialsProvider.create(credentials)); } /** - * Configure an {@link AWSCredentialsProvider}, required to calculate the - * signature. Alternatively, configure static {@link #credentials(AWSCredentials) + * Configure an {@link AwsCredentialsProvider}, required to calculate the + * signature. Alternatively, configure static {@link #credentials(AwsCredentials) * credentials}. * @param credentialsProvider must not be {@literal null}. * @return {@code this} {@link AwsIamAuthenticationOptionsBuilder}. - * @see #credentials(AWSCredentials) + * @see #credentials(AwsCredentials) */ - public AwsIamAuthenticationOptionsBuilder credentialsProvider(AWSCredentialsProvider credentialsProvider) { + public AwsIamAuthenticationOptionsBuilder credentialsProvider(AwsCredentialsProvider credentialsProvider) { - Assert.notNull(credentialsProvider, "AWSCredentialsProvider must not be null"); + Assert.notNull(credentialsProvider, "AwsCredentialsProvider must not be null"); this.credentialsProvider = credentialsProvider; return this; diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AwsIamAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AwsIamAuthenticationUnitTests.java index 77d21bbc..35a7f6dd 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AwsIamAuthenticationUnitTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AwsIamAuthenticationUnitTests.java @@ -17,7 +17,8 @@ package org.springframework.vault.authentication; import java.time.Duration; -import com.amazonaws.auth.BasicAWSCredentials; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -67,7 +68,7 @@ class AwsIamAuthenticationUnitTests { + "}")); AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder().role("foo-role") - .credentials(new BasicAWSCredentials("foo", "bar")).build(); + .credentials(AwsBasicCredentials.create("foo", "bar")).build(); AwsIamAuthentication sut = new AwsIamAuthentication(options, this.restTemplate); VaultToken login = sut.login(); @@ -90,7 +91,7 @@ class AwsIamAuthenticationUnitTests { + "}")); AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder().role("foo-role") - .credentials(new BasicAWSCredentials("foo", "bar")).build(); + .credentials(AwsBasicCredentials.create("foo", "bar")).build(); AuthenticationSteps steps = AwsIamAuthentication.createAuthenticationSteps(options); AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, this.restTemplate); diff --git a/spring-vault-dependencies/pom.xml b/spring-vault-dependencies/pom.xml index c420ff74..5c96d114 100644 --- a/spring-vault-dependencies/pom.xml +++ b/spring-vault-dependencies/pom.xml @@ -63,7 +63,7 @@ 4.1.72.Final 3.14.9 2.13.3 - 1.11.975 + 2.17.152 v1-rev20210226-1.31.0 1.2.2 0.22.2 @@ -131,8 +131,8 @@ - com.amazonaws - aws-java-sdk-core + software.amazon.awssdk + auth ${aws-java-sdk.version} true