Skip to content

Commit 413b425

Browse files
authored
Update presign interceptors to resolve auth scheme directly instead of reading SELECTED_AUTH_SCHEME (#6930)
* Update presign interceptors to resolve auth scheme directly instead of reading SELECTED_AUTH_SCHEME
1 parent 21e089f commit 413b425

10 files changed

Lines changed: 114 additions & 34 deletions

File tree

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/auth/AuthSchemeResolver.java renamed to core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16-
package software.amazon.awssdk.core.internal.http.auth;
16+
package software.amazon.awssdk.core.http.auth;
1717

1818
import java.time.Duration;
1919
import java.util.ArrayList;
@@ -22,13 +22,16 @@
2222
import java.util.concurrent.CompletableFuture;
2323
import java.util.function.Supplier;
2424
import java.util.stream.Collectors;
25-
import software.amazon.awssdk.annotations.SdkInternalApi;
25+
import software.amazon.awssdk.annotations.SdkProtectedApi;
26+
import software.amazon.awssdk.core.SdkRequest;
2627
import software.amazon.awssdk.core.SelectedAuthScheme;
2728
import software.amazon.awssdk.core.exception.SdkException;
2829
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
2930
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
3031
import software.amazon.awssdk.core.internal.util.MetricUtils;
3132
import software.amazon.awssdk.core.metrics.CoreMetric;
33+
import software.amazon.awssdk.core.spi.identity.AuthSchemeOptionsResolver;
34+
import software.amazon.awssdk.core.spi.identity.IdentityProviderUpdater;
3235
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
3336
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
3437
import software.amazon.awssdk.http.auth.spi.signer.HttpSigner;
@@ -45,14 +48,42 @@
4548
/**
4649
* Shared utility for selecting auth schemes from a list of options.
4750
*/
48-
@SdkInternalApi
51+
@SdkProtectedApi
4952
public final class AuthSchemeResolver {
5053

5154
private static final Logger LOG = Logger.loggerFor(AuthSchemeResolver.class);
5255

5356
private AuthSchemeResolver() {
5457
}
5558

59+
/**
60+
* Resolve an auth scheme from execution attributes, applying any identity provider overrides.
61+
* This is a convenience method for use by interceptors that need to resolve an auth scheme
62+
* outside of the normal pipeline flow (e.g., presign interceptors).
63+
*
64+
* @param request The SDK request (may contain credential overrides)
65+
* @param executionAttributes The execution attributes containing auth scheme resolution inputs
66+
* @return The selected auth scheme
67+
*/
68+
public static SelectedAuthScheme<? extends Identity> resolveAuthScheme(
69+
SdkRequest request, ExecutionAttributes executionAttributes) {
70+
AuthSchemeOptionsResolver optionsResolver =
71+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_OPTIONS_RESOLVER);
72+
Map<String, AuthScheme<?>> authSchemes =
73+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEMES);
74+
IdentityProviders identityProviders =
75+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDERS);
76+
77+
IdentityProviderUpdater updater =
78+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDER_UPDATER);
79+
if (updater != null) {
80+
identityProviders = updater.update(request, identityProviders, executionAttributes);
81+
}
82+
83+
List<AuthSchemeOption> authOptions = optionsResolver.resolve(request);
84+
return selectAuthScheme(authOptions, authSchemes, identityProviders, null);
85+
}
86+
5687
/**
5788
* Select an auth scheme from the given options.
5889
*

‎core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
import software.amazon.awssdk.core.RequestOverrideConfiguration;
2222
import software.amazon.awssdk.core.SdkRequest;
2323
import software.amazon.awssdk.core.SelectedAuthScheme;
24+
import software.amazon.awssdk.core.http.auth.AuthSchemeResolver;
2425
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
2526
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
2627
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
2728
import software.amazon.awssdk.core.internal.http.HttpClientDependencies;
2829
import software.amazon.awssdk.core.internal.http.RequestExecutionContext;
29-
import software.amazon.awssdk.core.internal.http.auth.AuthSchemeResolver;
3030
import software.amazon.awssdk.core.internal.http.pipeline.MutableRequestToRequestPipeline;
3131
import software.amazon.awssdk.core.spi.identity.AuthSchemeOptionsResolver;
3232
import software.amazon.awssdk.core.spi.identity.IdentityProviderUpdater;

‎core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/auth/AuthSchemeResolverTest.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.junit.jupiter.api.Test;
3232
import software.amazon.awssdk.core.SelectedAuthScheme;
3333
import software.amazon.awssdk.core.exception.SdkException;
34+
import software.amazon.awssdk.core.http.auth.AuthSchemeResolver;
3435
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3536
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
3637
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;

‎services/docdb/src/main/java/software/amazon/awssdk/services/docdb/internal/RdsPresignInterceptor.java‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
package software.amazon.awssdk.services.docdb.internal;
1717

18-
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME;
1918

2019
import java.net.URI;
2120
import java.time.Clock;
@@ -32,6 +31,7 @@
3231
import software.amazon.awssdk.core.SelectedAuthScheme;
3332
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3433
import software.amazon.awssdk.core.client.config.SdkClientOption;
34+
import software.amazon.awssdk.core.http.auth.AuthSchemeResolver;
3535
import software.amazon.awssdk.core.interceptor.Context;
3636
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3737
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
@@ -106,7 +106,7 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
106106
return request.toBuilder().removeQueryParameter(PARAM_SOURCE_REGION).build();
107107
}
108108

109-
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
109+
SelectedAuthScheme<?> selectedAuthScheme = resolveAuthScheme(context.request(), executionAttributes);
110110
String sourceRegion = presignableRequest.getSourceRegion();
111111
String destinationRegion = selectedAuthScheme.authSchemeOption().signerProperty(AwsV4HttpSigner.REGION_NAME);
112112
URI endpoint = createEndpoint(sourceRegion, SERVICE_NAME, executionAttributes);
@@ -118,7 +118,7 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
118118
.removeQueryParameter(PARAM_SOURCE_REGION)
119119
.build();
120120

121-
requestToPresign = sraPresignRequest(executionAttributes, requestToPresign, sourceRegion);
121+
requestToPresign = sraPresignRequest(selectedAuthScheme, requestToPresign, sourceRegion);
122122

123123
String presignedUrl = requestToPresign.getUri().toString();
124124

@@ -129,6 +129,14 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
129129
.build();
130130
}
131131

132+
/**
133+
* Resolves the auth scheme from execution attributes, applying any request-level credential overrides.
134+
*/
135+
private SelectedAuthScheme<? extends Identity> resolveAuthScheme(SdkRequest request,
136+
ExecutionAttributes executionAttributes) {
137+
return AuthSchemeResolver.resolveAuthScheme(request, executionAttributes);
138+
}
139+
132140
/**
133141
* Adapts the request to the {@link PresignableRequest}.
134142
*
@@ -159,11 +167,8 @@ private PresignableRequest toPresignableRequest(SdkHttpRequest request, Context.
159167
/**
160168
* Presign the provided HTTP request using SRA HttpSigner
161169
*/
162-
private SdkHttpFullRequest sraPresignRequest(ExecutionAttributes executionAttributes, SdkHttpFullRequest request,
170+
private SdkHttpFullRequest sraPresignRequest(SelectedAuthScheme<?> selectedAuthScheme, SdkHttpFullRequest request,
163171
String signingRegion) {
164-
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
165-
166-
167172
Instant signingInstant;
168173
if (signingClockOverride != null) {
169174
signingInstant = signingClockOverride.instant();

‎services/ec2/src/main/java/software/amazon/awssdk/services/ec2/transform/internal/GeneratePreSignUrlInterceptor.java‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
package software.amazon.awssdk.services.ec2.transform.internal;
1717

18-
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME;
1918

2019
import java.net.URI;
2120
import java.time.Clock;
@@ -32,6 +31,7 @@
3231
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3332
import software.amazon.awssdk.core.client.config.SdkClientOption;
3433
import software.amazon.awssdk.core.exception.SdkClientException;
34+
import software.amazon.awssdk.core.http.auth.AuthSchemeResolver;
3535
import software.amazon.awssdk.core.interceptor.Context;
3636
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3737
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
@@ -131,7 +131,7 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, Execu
131131
.build();
132132

133133
URI presignedUrl =
134-
sraPresignRequest(executionAttributes, requestForPresigning, sourceRegion);
134+
sraPresignRequest(context.request(), executionAttributes, requestForPresigning, sourceRegion);
135135

136136
return request.toBuilder()
137137
.putRawQueryParameter("DestinationRegion", destinationRegion)
@@ -142,9 +142,14 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, Execu
142142
return request;
143143
}
144144

145-
private URI sraPresignRequest(ExecutionAttributes executionAttributes, SdkHttpFullRequest request,
146-
String signingRegion) {
147-
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
145+
private SelectedAuthScheme<? extends Identity> resolveAuthScheme(SdkRequest request,
146+
ExecutionAttributes executionAttributes) {
147+
return AuthSchemeResolver.resolveAuthScheme(request, executionAttributes);
148+
}
149+
150+
private URI sraPresignRequest(SdkRequest sdkRequest, ExecutionAttributes executionAttributes,
151+
SdkHttpFullRequest request, String signingRegion) {
152+
SelectedAuthScheme<?> selectedAuthScheme = resolveAuthScheme(sdkRequest, executionAttributes);
148153
Instant signingInstant;
149154
if (testClock != null) {
150155
signingInstant = testClock.instant();

‎services/ec2/src/test/java/software/amazon/awssdk/services/ec2/transform/internal/GeneratePreSignUrlInterceptorTest.java‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,24 @@
2525
import java.time.Instant;
2626
import java.time.ZoneId;
2727
import java.time.ZonedDateTime;
28+
import java.util.Collections;
29+
import java.util.Map;
2830
import org.junit.Test;
2931
import org.junit.runner.RunWith;
3032
import org.mockito.Mock;
3133
import org.mockito.junit.MockitoJUnitRunner;
3234
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
35+
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
3336
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
3437
import software.amazon.awssdk.core.interceptor.Context;
3538
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
39+
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
3640
import software.amazon.awssdk.http.SdkHttpFullRequest;
3741
import software.amazon.awssdk.http.SdkHttpMethod;
3842
import software.amazon.awssdk.http.SdkHttpRequest;
43+
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4AuthScheme;
44+
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
45+
import software.amazon.awssdk.identity.spi.IdentityProviders;
3946
import software.amazon.awssdk.services.ec2.model.CopySnapshotRequest;
4047

4148
@RunWith(MockitoJUnitRunner.class)
@@ -63,6 +70,7 @@ public void copySnapshotRequest_httpsProtocolAddedToEndpoint() {
6370
ExecutionAttributes attrs = new ExecutionAttributes();
6471
attrs.putAttribute(AWS_CREDENTIALS, AwsBasicCredentials.create("foo", "bar"));
6572
attrs.putAttribute(AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME, "ec2");
73+
addSraAttributes(attrs, AwsBasicCredentials.create("foo", "bar"));
6674

6775
SdkHttpRequest modifiedRequest = INTERCEPTOR.modifyHttpRequest(mockContext, attrs);
6876

@@ -116,11 +124,31 @@ public void copySnapshotRequest_generatesCorrectPresignedUrl() {
116124
ExecutionAttributes attrs = new ExecutionAttributes();
117125
attrs.putAttribute(AWS_CREDENTIALS, AwsBasicCredentials.create("akid", "skid"));
118126
attrs.putAttribute(AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME, "ec2");
127+
addSraAttributes(attrs, AwsBasicCredentials.create("akid", "skid"));
119128

120129
SdkHttpRequest modifiedRequest = interceptor.modifyHttpRequest(mockContext, attrs);
121130

122131
String generatedPresignedUrl = modifiedRequest.rawQueryParameters().get("PresignedUrl").get(0);
123132

124133
assertThat(generatedPresignedUrl).isEqualTo(expectedPresignedUrl);
125134
}
135+
136+
private static void addSraAttributes(ExecutionAttributes attrs, AwsBasicCredentials credentials) {
137+
AwsV4AuthScheme authScheme = AwsV4AuthScheme.create();
138+
Map<String, AuthScheme<?>> authSchemes = Collections.singletonMap(authScheme.schemeId(), authScheme);
139+
IdentityProviders identityProviders = IdentityProviders.builder()
140+
.putIdentityProvider(StaticCredentialsProvider.create(credentials))
141+
.build();
142+
attrs.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEMES, authSchemes);
143+
attrs.putAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDERS, identityProviders);
144+
attrs.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_OPTIONS_RESOLVER,
145+
request -> Collections.singletonList(
146+
software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption.builder()
147+
.schemeId(authScheme.schemeId())
148+
.putSignerProperty(software.amazon.awssdk.http.auth.aws.signer.AwsV4FamilyHttpSigner
149+
.SERVICE_SIGNING_NAME, "ec2")
150+
.putSignerProperty(software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner
151+
.REGION_NAME, "us-west-2")
152+
.build()));
153+
}
126154
}

‎services/neptune/src/main/java/software/amazon/awssdk/services/neptune/internal/RdsPresignInterceptor.java‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
package software.amazon.awssdk.services.neptune.internal;
1717

18-
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME;
1918

2019
import java.net.URI;
2120
import java.time.Clock;
@@ -32,6 +31,7 @@
3231
import software.amazon.awssdk.core.SelectedAuthScheme;
3332
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3433
import software.amazon.awssdk.core.client.config.SdkClientOption;
34+
import software.amazon.awssdk.core.http.auth.AuthSchemeResolver;
3535
import software.amazon.awssdk.core.interceptor.Context;
3636
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3737
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
@@ -51,7 +51,6 @@
5151
import software.amazon.awssdk.services.neptune.model.NeptuneRequest;
5252
import software.amazon.awssdk.utils.CompletableFutureUtils;
5353

54-
5554
/**
5655
* Abstract pre-sign handler that follows the pre-signing scheme outlined in the 'RDS Presigned URL for Cross-Region Copying'
5756
* SEP.
@@ -107,7 +106,7 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
107106
return request.toBuilder().removeQueryParameter(PARAM_SOURCE_REGION).build();
108107
}
109108

110-
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
109+
SelectedAuthScheme<?> selectedAuthScheme = resolveAuthScheme(context.request(), executionAttributes);
111110
String sourceRegion = presignableRequest.getSourceRegion();
112111
String destinationRegion = selectedAuthScheme.authSchemeOption().signerProperty(AwsV4HttpSigner.REGION_NAME);
113112
URI endpoint = createEndpoint(sourceRegion, SERVICE_NAME, executionAttributes);
@@ -119,7 +118,7 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
119118
.removeQueryParameter(PARAM_SOURCE_REGION)
120119
.build();
121120

122-
requestToPresign = sraPresignRequest(executionAttributes, requestToPresign, sourceRegion);
121+
requestToPresign = sraPresignRequest(selectedAuthScheme, requestToPresign, sourceRegion);
123122

124123
String presignedUrl = requestToPresign.getUri().toString();
125124

@@ -130,6 +129,14 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
130129
.build();
131130
}
132131

132+
/**
133+
* Resolves the auth scheme from execution attributes, applying any request-level credential overrides.
134+
*/
135+
private SelectedAuthScheme<? extends Identity> resolveAuthScheme(SdkRequest request,
136+
ExecutionAttributes executionAttributes) {
137+
return AuthSchemeResolver.resolveAuthScheme(request, executionAttributes);
138+
}
139+
133140
/**
134141
* Adapts the request to the {@link PresignableRequest}.
135142
*
@@ -160,11 +167,8 @@ private PresignableRequest toPresignableRequest(SdkHttpRequest request, Context.
160167
/**
161168
* Presign the provided HTTP request using SRA HttpSigner
162169
*/
163-
private SdkHttpFullRequest sraPresignRequest(ExecutionAttributes executionAttributes, SdkHttpFullRequest request,
170+
private SdkHttpFullRequest sraPresignRequest(SelectedAuthScheme<?> selectedAuthScheme, SdkHttpFullRequest request,
164171
String signingRegion) {
165-
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
166-
167-
168172
Instant signingInstant;
169173
if (signingClockOverride != null) {
170174
signingInstant = signingClockOverride.instant();

0 commit comments

Comments
 (0)