Skip to content

Commit 53f5cb3

Browse files
authored
Accept and use the new AWS Credentials interfaces (#3829)
* Accept and use the new AWS Credentials interfaces In AwsClientBuilder and other places where customers used to be able to provide AwsCredentialsProvider. * Update client codegen for endpoint discovery * Address some of Matt's feedback * Switch one usage of overrideConfiguration.credentialsProvider To use the new credentialsIdentityProvider() instead. * Update tests to mock new IdentityProvider * Handle null for CredentialUtils conversion methods * Add IdentityProvider overload to S3CrtAsyncClientBuilder * Add a TODO for removing a join() later * Add TODO for AwsCredentialsProviderChain * Add unit tests and few other minor changes * Remove unnecessary fallback from AuthorizationStrategyFactory * Fix test in S3 * Address PR feedback
1 parent aa6afee commit 53f5cb3

File tree

40 files changed

+761
-214
lines changed

40 files changed

+761
-214
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,11 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
363363
builder.beginControlFlow("if (endpointDiscoveryEnabled)");
364364

365365
builder.addCode("$T key = $N.overrideConfiguration()", String.class, opModel.getInput().getVariableName())
366-
.addCode(" .flatMap($T::credentialsProvider)", AwsRequestOverrideConfiguration.class)
367-
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_PROVIDER))", AwsClientOption.class)
368-
.addCode(" .resolveCredentials().accessKeyId();");
366+
.addCode(" .flatMap($T::credentialsIdentityProvider)", AwsRequestOverrideConfiguration.class)
367+
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_IDENTITY_PROVIDER))",
368+
AwsClientOption.class)
369+
// TODO: avoid join inside async
370+
.addCode(" .resolveIdentity().join().accessKeyId();");
369371

370372
builder.addCode("$1T endpointDiscoveryRequest = $1T.builder()", EndpointDiscoveryRequest.class)
371373
.addCode(" .required($L)", opModel.getInputShape().getEndpointDiscovery().isRequired())

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,10 @@ private List<MethodSpec> operationMethodSpecs(OperationModel opModel) {
244244
method.beginControlFlow("if (endpointDiscoveryEnabled)");
245245

246246
method.addCode("$T key = $N.overrideConfiguration()", String.class, opModel.getInput().getVariableName())
247-
.addCode(" .flatMap($T::credentialsProvider)", AwsRequestOverrideConfiguration.class)
248-
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_PROVIDER))", AwsClientOption.class)
249-
.addCode(" .resolveCredentials().accessKeyId();");
247+
.addCode(" .flatMap($T::credentialsIdentityProvider)", AwsRequestOverrideConfiguration.class)
248+
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_IDENTITY_PROVIDER))",
249+
AwsClientOption.class)
250+
.addCode(" .resolveIdentity().join().accessKeyId();");
250251

251252
method.addCode("$1T endpointDiscoveryRequest = $1T.builder()", EndpointDiscoveryRequest.class)
252253
.addCode(" .required($L)", opModel.getInputShape().getEndpointDiscovery().isRequired())

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ public CompletableFuture<TestDiscoveryIdentifiersRequiredResponse> testDiscovery
174174
URI cachedEndpoint = null;
175175
if (endpointDiscoveryEnabled) {
176176
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
177-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
178-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
179-
.accessKeyId();
177+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
178+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
179+
.resolveIdentity().join().accessKeyId();
180180
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
181181
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
182182
.overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null))
@@ -242,9 +242,9 @@ public CompletableFuture<TestDiscoveryOptionalResponse> testDiscoveryOptional(
242242
URI cachedEndpoint = null;
243243
if (endpointDiscoveryEnabled) {
244244
String key = testDiscoveryOptionalRequest.overrideConfiguration()
245-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
246-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
247-
.accessKeyId();
245+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
246+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
247+
.resolveIdentity().join().accessKeyId();
248248
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false)
249249
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
250250
.overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build();
@@ -317,9 +317,9 @@ public CompletableFuture<TestDiscoveryRequiredResponse> testDiscoveryRequired(
317317
URI cachedEndpoint = null;
318318
if (endpointDiscoveryEnabled) {
319319
String key = testDiscoveryRequiredRequest.overrideConfiguration()
320-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
321-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
322-
.accessKeyId();
320+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
321+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
322+
.resolveIdentity().join().accessKeyId();
323323
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
324324
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
325325
.overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build();

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ public TestDiscoveryIdentifiersRequiredResponse testDiscoveryIdentifiersRequired
151151
URI cachedEndpoint = null;
152152
if (endpointDiscoveryEnabled) {
153153
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
154-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
155-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
156-
.accessKeyId();
154+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
155+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
156+
.resolveIdentity().join().accessKeyId();
157157
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
158158
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
159159
.overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)).build();
@@ -208,9 +208,9 @@ public TestDiscoveryOptionalResponse testDiscoveryOptional(TestDiscoveryOptional
208208
URI cachedEndpoint = null;
209209
if (endpointDiscoveryEnabled) {
210210
String key = testDiscoveryOptionalRequest.overrideConfiguration()
211-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
212-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
213-
.accessKeyId();
211+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
212+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
213+
.resolveIdentity().join().accessKeyId();
214214
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false)
215215
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
216216
.overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build();
@@ -272,9 +272,9 @@ public TestDiscoveryRequiredResponse testDiscoveryRequired(TestDiscoveryRequired
272272
URI cachedEndpoint = null;
273273
if (endpointDiscoveryEnabled) {
274274
String key = testDiscoveryRequiredRequest.overrideConfiguration()
275-
.flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
276-
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
277-
.accessKeyId();
275+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
276+
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
277+
.resolveIdentity().join().accessKeyId();
278278
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
279279
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
280280
.overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build();

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
package software.amazon.awssdk.auth.credentials;
1717

1818
import software.amazon.awssdk.annotations.SdkProtectedApi;
19+
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
20+
import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
21+
import software.amazon.awssdk.identity.spi.IdentityProvider;
1922

2023
@SdkProtectedApi
2124
public final class CredentialUtils {
@@ -28,6 +31,76 @@ private CredentialUtils() {
2831
* authenticate themselves.
2932
*/
3033
public static boolean isAnonymous(AwsCredentials credentials) {
34+
return isAnonymous((AwsCredentialsIdentity) credentials);
35+
}
36+
37+
/**
38+
* Determine whether the provided credentials are anonymous credentials, indicating that the customer is not attempting to
39+
* authenticate themselves.
40+
*/
41+
public static boolean isAnonymous(AwsCredentialsIdentity credentials) {
3142
return credentials.secretAccessKey() == null && credentials.accessKeyId() == null;
3243
}
44+
45+
/**
46+
* Converts an {@link AwsCredentialsIdentity} to {@link AwsCredentials}.
47+
*
48+
* <p>Usage of the new AwsCredentialsIdentity type is preferred over AwsCredentials. But some places may need to still
49+
* convert to the older AwsCredentials type to work with existing code.</p>
50+
*
51+
* <p>The conversion is only aware of {@link AwsCredentialsIdentity} and {@link AwsSessionCredentialsIdentity} types. If the
52+
* input is another sub-type that has other properties, they are not carried over. i.e.,
53+
* <ul>
54+
* <li>AwsSessionCredentialsIdentity -> AwsSessionCredentials</li>
55+
* <li>AwsCredentialsIdentity -> AwsBasicCredentials</li>
56+
* </ul>
57+
* </p>
58+
*
59+
* @param awsCredentialsIdentity The {@link AwsCredentialsIdentity} to convert
60+
* @return The corresponding {@link AwsCredentials}
61+
*/
62+
public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentialsIdentity) {
63+
if (awsCredentialsIdentity == null) {
64+
return null;
65+
}
66+
if (awsCredentialsIdentity instanceof AwsCredentials) {
67+
return (AwsCredentials) awsCredentialsIdentity;
68+
}
69+
70+
// identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
71+
if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
72+
AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
73+
return AwsSessionCredentials.create(awsSessionCredentialsIdentity.accessKeyId(),
74+
awsSessionCredentialsIdentity.secretAccessKey(),
75+
awsSessionCredentialsIdentity.sessionToken());
76+
}
77+
if (isAnonymous(awsCredentialsIdentity)) {
78+
return AwsBasicCredentials.ANONYMOUS_CREDENTIALS;
79+
}
80+
return AwsBasicCredentials.create(awsCredentialsIdentity.accessKeyId(),
81+
awsCredentialsIdentity.secretAccessKey());
82+
}
83+
84+
/**
85+
* Converts an {@link IdentityProvider<? extends AwsCredentialsIdentity>} to {@link AwsCredentialsProvider} based on
86+
* {@link #toCredentials(AwsCredentialsIdentity)}.
87+
*
88+
* <p>Usage of the new IdentityProvider type is preferred over AwsCredentialsProvider. But some places may need to still
89+
* convert to the older AwsCredentialsProvider type to work with existing code.
90+
* </p>
91+
*
92+
* @param identityProvider The {@link IdentityProvider<? extends AwsCredentialsIdentity>} to convert
93+
* @return The corresponding {@link AwsCredentialsProvider}
94+
*/
95+
public static AwsCredentialsProvider toCredentialsProvider(
96+
IdentityProvider<? extends AwsCredentialsIdentity> identityProvider) {
97+
if (identityProvider == null) {
98+
return null;
99+
}
100+
return () -> {
101+
// TODO: Exception handling for CompletionException thrown from join?
102+
AwsCredentialsIdentity awsCredentialsIdentity = identityProvider.resolveIdentity().join();
103+
return toCredentials(awsCredentialsIdentity);
104+
};
105+
}
33106
}

0 commit comments

Comments
 (0)