Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletionException;
import java.util.function.Supplier;
import javax.lang.model.element.Modifier;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.AwsS3V4Signer;
import software.amazon.awssdk.auth.signer.SignerLoader;
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
import software.amazon.awssdk.awscore.endpoints.AwsEndpointAttribute;
import software.amazon.awssdk.awscore.endpoints.authscheme.EndpointAuthScheme;
import software.amazon.awssdk.awscore.endpoints.authscheme.SigV4AuthScheme;
import software.amazon.awssdk.awscore.endpoints.authscheme.SigV4aAuthScheme;
import software.amazon.awssdk.awscore.util.SignerOverrideUtils;
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
import software.amazon.awssdk.codegen.model.rules.endpoints.ParameterModel;
Expand All @@ -58,6 +63,7 @@
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.endpoints.Endpoint;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4AuthScheme;
Expand All @@ -76,6 +82,7 @@ public class EndpointResolverInterceptorSpec implements ClassSpec {
private final EndpointRulesSpecUtils endpointRulesSpecUtils;
private final PoetExtension poetExtension;
private final boolean dependsOnHttpAuthAws;
private final boolean useSraAuth;

public EndpointResolverInterceptorSpec(IntermediateModel model) {
this.model = model;
Expand All @@ -87,6 +94,8 @@ public EndpointResolverInterceptorSpec(IntermediateModel model) {
Set<Class<?>> supportedAuthSchemes = new AuthSchemeSpecUtils(model).allServiceConcreteAuthSchemeClasses();
this.dependsOnHttpAuthAws = supportedAuthSchemes.contains(AwsV4AuthScheme.class) ||
supportedAuthSchemes.contains(AwsV4aAuthScheme.class);

this.useSraAuth = new AuthSchemeSpecUtils(model).useSraAuth();
}

@Override
Expand Down Expand Up @@ -114,6 +123,10 @@ public TypeSpec poetSpec() {

b.addMethod(hostPrefixMethod());

if (!useSraAuth) {
b.addMethod(signerProviderMethod());
}

return b.build();
}

Expand Down Expand Up @@ -156,7 +169,8 @@ private MethodSpec modifyRequestMethod() {
b.endControlFlow();


// If the endpoint resolver returns auth settings, use them as signer properties
// If the endpoint resolver returns auth settings, use them as signer properties.
// This effectively works to set the preSRA Signer ExecutionAttributes, so it is not conditional on useSraAuth.
b.addStatement("$T<$T> endpointAuthSchemes = endpoint.attribute($T.AUTH_SCHEMES)",
List.class, EndpointAuthScheme.class, AwsEndpointAttribute.class);
b.addStatement("$T<?> selectedAuthScheme = executionAttributes.getAttribute($T.SELECTED_AUTH_SCHEME)",
Expand All @@ -168,6 +182,17 @@ private MethodSpec modifyRequestMethod() {
SdkInternalExecutionAttribute.class);
b.endControlFlow();

// For pre SRA client, use Signer as determined by endpoint resolved auth scheme
if (!useSraAuth) {
b.beginControlFlow("if (endpointAuthSchemes != null)");
b.addStatement("$T chosenAuthScheme = $T.chooseAuthScheme(endpointAuthSchemes)", EndpointAuthScheme.class,
endpointRulesSpecUtils.rulesRuntimeClassName("AuthSchemeUtils"));
b.addStatement("$T<$T> signerProvider = signerProvider(chosenAuthScheme)", Supplier.class, Signer.class);
b.addStatement("result = $T.overrideSignerIfNotOverridden(result, executionAttributes, signerProvider)",
SignerOverrideUtils.class);
b.endControlFlow();
}

b.addStatement("executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, endpoint)");
b.addStatement("return result");
b.endControlFlow();
Expand Down Expand Up @@ -607,4 +632,36 @@ private static CodeBlock copyV4aEndpointSignerPropertiesToAuth() {
code.endControlFlow();
return code.build();
}

private MethodSpec signerProviderMethod() {
MethodSpec.Builder builder = MethodSpec.methodBuilder("signerProvider")
.addModifiers(Modifier.PRIVATE)
.addParameter(EndpointAuthScheme.class, "authScheme")
.returns(ParameterizedTypeName.get(Supplier.class, Signer.class));

builder.beginControlFlow("switch (authScheme.name())");
builder.addCode("case $S:", "sigv4");
if (endpointRulesSpecUtils.isS3() || endpointRulesSpecUtils.isS3Control()) {
builder.addStatement("return $T::create", AwsS3V4Signer.class);
} else {
builder.addStatement("return $T::create", Aws4Signer.class);
}

builder.addCode("case $S:", "sigv4a");
if (endpointRulesSpecUtils.isS3() || endpointRulesSpecUtils.isS3Control()) {
builder.addStatement("return $T::getS3SigV4aSigner", SignerLoader.class);
} else {
builder.addStatement("return $T::getSigV4aSigner", SignerLoader.class);
}

builder.addCode("default:");
builder.addStatement("break");
builder.endControlFlow();

builder.addStatement("throw $T.create($S + authScheme.name())",
SdkClientException.class,
"Don't know how to create signer for auth scheme: ");

return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
import software.amazon.awssdk.identity.spi.Identity;
import software.amazon.awssdk.utils.Logger;

// TODO(sra-identity-auth): seems like this can be SdkInternalApi, similar to other .resource files in this folder,
// since they are generated in each service module
@SdkProtectedApi
public final class AuthSchemeUtils {
private static final Logger LOG = Logger.loggerFor(AuthSchemeUtils.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletionException;
import java.util.function.Supplier;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.SignerLoader;
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
import software.amazon.awssdk.awscore.endpoints.AwsEndpointAttribute;
import software.amazon.awssdk.awscore.endpoints.authscheme.EndpointAuthScheme;
import software.amazon.awssdk.awscore.endpoints.authscheme.SigV4AuthScheme;
import software.amazon.awssdk.awscore.endpoints.authscheme.SigV4aAuthScheme;
import software.amazon.awssdk.awscore.util.SignerOverrideUtils;
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.core.SelectedAuthScheme;
import software.amazon.awssdk.core.exception.SdkClientException;
Expand All @@ -18,6 +22,7 @@
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.endpoints.Endpoint;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner;
Expand Down Expand Up @@ -58,6 +63,11 @@ public SdkRequest modifyRequest(Context.ModifyRequest context, ExecutionAttribut
selectedAuthScheme = authSchemeWithEndpointSignerProperties(endpointAuthSchemes, selectedAuthScheme);
executionAttributes.putAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME, selectedAuthScheme);
}
if (endpointAuthSchemes != null) {
EndpointAuthScheme chosenAuthScheme = AuthSchemeUtils.chooseAuthScheme(endpointAuthSchemes);
Supplier<Signer> signerProvider = signerProvider(chosenAuthScheme);
result = SignerOverrideUtils.overrideSignerIfNotOverridden(result, executionAttributes, signerProvider);
}
executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, endpoint);
return result;
} catch (CompletionException e) {
Expand Down Expand Up @@ -176,4 +186,16 @@ private static Optional<String> hostPrefix(String operationName, SdkRequest requ
return Optional.empty();
}
}

private Supplier<Signer> signerProvider(EndpointAuthScheme authScheme) {
switch (authScheme.name()) {
case "sigv4":
return Aws4Signer::create;
case "sigv4a":
return SignerLoader::getSigV4aSigner;
default:
break;
}
throw SdkClientException.create("Don't know how to create signer for auth scheme: " + authScheme.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@
"software.amazon.awssdk.services.s3.internal.handlers.CopySourceInterceptor"
],
"requiredTraitValidationEnabled": true,
"useSraAuth": true,
"enableEndpointAuthSchemeParams": true,
"customClientContextParams":{
"CrossRegionAccessEnabled":{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void setup() {
}

@Test
@Disabled // Related to the TODO above on MULTI_REGION_ENDPOINT
public void multiRegionArn_correctlyRewritesEndpoint() throws Exception {
mockHttpClient.stubNextResponse(mockListObjectsResponse());
S3Client s3Client = clientBuilder().serviceConfiguration(S3Configuration.builder().build()).build();
Expand All @@ -61,6 +62,7 @@ public void multiRegionArn_correctlyRewritesEndpoint() throws Exception {
}

@Test
@Disabled // Related to the TODO above on MULTI_REGION_ENDPOINT
public void multiRegionArn_useArnRegionEnabled_correctlyRewritesEndpoint() throws Exception {
mockHttpClient.stubNextResponse(mockListObjectsResponse());
S3Client s3Client = clientBuilder().serviceConfiguration(S3Configuration.builder()
Expand Down Expand Up @@ -137,6 +139,7 @@ public void multiRegionArn_pathStyle_throwsIllegalArgumentException() throws Exc
}

@Test
@Disabled // Related to the TODO above on MULTI_REGION_ENDPOINT
public void multiRegionArn_differentRegion_useArnRegionTrue() throws Exception {
mockHttpClient.stubNextResponse(mockListObjectsResponse());
S3Client s3Client = clientBuilder().build();
Expand Down