Skip to content

Commit ede03d1

Browse files
authored
Remove the use of the legacy signer (#4941)
* Remove the use of the legacy signer * Remove extra whitespace * Small commit to kick the build * Remove the profiles dependency that is not needed anymore
1 parent 0f22139 commit ede03d1

File tree

12 files changed

+1226
-557
lines changed

12 files changed

+1226
-557
lines changed

services/docdb/pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@
5656
<artifactId>aws-query-protocol</artifactId>
5757
<version>${awsjavasdk.version}</version>
5858
</dependency>
59-
<dependency>
60-
<groupId>software.amazon.awssdk</groupId>
61-
<artifactId>profiles</artifactId>
62-
<version>${awsjavasdk.version}</version>
63-
</dependency>
6459
<dependency>
6560
<groupId>software.amazon.awssdk</groupId>
6661
<artifactId>http-auth-aws</artifactId>

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

Lines changed: 102 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,20 @@
1515

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

18-
import static software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute.AWS_CREDENTIALS;
1918
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME;
2019

2120
import java.net.URI;
2221
import java.time.Clock;
22+
import java.time.Duration;
23+
import java.time.Instant;
24+
import java.time.ZoneOffset;
25+
import java.util.concurrent.CompletableFuture;
2326
import software.amazon.awssdk.annotations.SdkInternalApi;
24-
import software.amazon.awssdk.auth.credentials.AwsCredentials;
25-
import software.amazon.awssdk.auth.credentials.CredentialUtils;
26-
import software.amazon.awssdk.auth.signer.Aws4Signer;
27-
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
28-
import software.amazon.awssdk.auth.signer.params.Aws4PresignerParams;
2927
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
3028
import software.amazon.awssdk.awscore.endpoint.DefaultServiceEndpointBuilder;
3129
import software.amazon.awssdk.core.Protocol;
3230
import software.amazon.awssdk.core.SdkRequest;
31+
import software.amazon.awssdk.core.SelectedAuthScheme;
3332
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3433
import software.amazon.awssdk.core.client.config.SdkClientOption;
3534
import software.amazon.awssdk.core.exception.SdkClientException;
@@ -40,7 +39,13 @@
4039
import software.amazon.awssdk.http.SdkHttpFullRequest;
4140
import software.amazon.awssdk.http.SdkHttpMethod;
4241
import software.amazon.awssdk.http.SdkHttpRequest;
43-
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
42+
import software.amazon.awssdk.http.auth.aws.signer.AwsV4FamilyHttpSigner;
43+
import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner;
44+
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
45+
import software.amazon.awssdk.http.auth.spi.signer.HttpSigner;
46+
import software.amazon.awssdk.http.auth.spi.signer.SignRequest;
47+
import software.amazon.awssdk.http.auth.spi.signer.SignedRequest;
48+
import software.amazon.awssdk.identity.spi.Identity;
4449
import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory;
4550
import software.amazon.awssdk.regions.Region;
4651
import software.amazon.awssdk.services.docdb.model.DocDbRequest;
@@ -79,49 +84,39 @@ public interface PresignableRequest {
7984

8085
private final Class<T> requestClassToPreSign;
8186

82-
private final Clock signingOverrideClock;
87+
private final Clock signingClockOverride;
8388

8489
protected RdsPresignInterceptor(Class<T> requestClassToPreSign) {
8590
this(requestClassToPreSign, null);
8691
}
8792

88-
protected RdsPresignInterceptor(Class<T> requestClassToPreSign, Clock signingOverrideClock) {
93+
protected RdsPresignInterceptor(Class<T> requestClassToPreSign, Clock signingClockOverride) {
8994
this.requestClassToPreSign = requestClassToPreSign;
90-
this.signingOverrideClock = signingOverrideClock;
95+
this.signingClockOverride = signingClockOverride;
9196
}
9297

9398
@Override
9499
public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
95-
ExecutionAttributes executionAttributes) {
100+
ExecutionAttributes executionAttributes) {
96101
SdkHttpRequest request = context.httpRequest();
97-
SdkRequest originalRequest = context.request();
98-
if (!requestClassToPreSign.isInstance(originalRequest)) {
99-
return request;
100-
}
101-
102-
if (request.firstMatchingRawQueryParameter(PARAM_PRESIGNED_URL).isPresent()) {
103-
return request;
102+
PresignableRequest presignableRequest = toPresignableRequest(request, context);
103+
if (presignableRequest == null) {
104+
return request.toBuilder().removeQueryParameter(PARAM_SOURCE_REGION).build();
104105
}
105106

106-
PresignableRequest presignableRequest = adaptRequest(requestClassToPreSign.cast(originalRequest));
107-
107+
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
108108
String sourceRegion = presignableRequest.getSourceRegion();
109-
if (sourceRegion == null) {
110-
return request;
111-
}
112-
113-
String destinationRegion = executionAttributes.getAttribute(AwsSignerExecutionAttribute.SIGNING_REGION).id();
114-
109+
String destinationRegion = selectedAuthScheme.authSchemeOption().signerProperty(AwsV4HttpSigner.REGION_NAME);
115110
URI endpoint = createEndpoint(sourceRegion, SERVICE_NAME, executionAttributes);
116111
SdkHttpFullRequest.Builder marshalledRequest = presignableRequest.marshall().toBuilder().uri(endpoint);
117112

118113
SdkHttpFullRequest requestToPresign =
119-
marshalledRequest.method(SdkHttpMethod.GET)
120-
.putRawQueryParameter(PARAM_DESTINATION_REGION, destinationRegion)
121-
.removeQueryParameter(PARAM_SOURCE_REGION)
122-
.build();
114+
marshalledRequest.method(SdkHttpMethod.GET)
115+
.putRawQueryParameter(PARAM_DESTINATION_REGION, destinationRegion)
116+
.removeQueryParameter(PARAM_SOURCE_REGION)
117+
.build();
123118

124-
requestToPresign = presignRequest(requestToPresign, executionAttributes, sourceRegion);
119+
requestToPresign = sraPresignRequest(executionAttributes, requestToPresign, sourceRegion);
125120

126121
String presignedUrl = requestToPresign.getUri().toString();
127122

@@ -140,39 +135,93 @@ public final SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
140135
*/
141136
protected abstract PresignableRequest adaptRequest(T originalRequest);
142137

143-
private SdkHttpFullRequest presignRequest(SdkHttpFullRequest request,
144-
ExecutionAttributes attributes,
145-
String signingRegion) {
138+
/**
139+
* Converts the request to a PresignableRequest if possible.
140+
*/
141+
private PresignableRequest toPresignableRequest(SdkHttpRequest request, Context.ModifyHttpRequest context) {
142+
SdkRequest originalRequest = context.request();
143+
if (!requestClassToPreSign.isInstance(originalRequest)) {
144+
return null;
145+
}
146+
if (request.firstMatchingRawQueryParameter(PARAM_PRESIGNED_URL).isPresent()) {
147+
return null;
148+
}
149+
PresignableRequest presignableRequest = adaptRequest(requestClassToPreSign.cast(originalRequest));
150+
String sourceRegion = presignableRequest.getSourceRegion();
151+
if (sourceRegion == null) {
152+
return null;
153+
}
154+
return presignableRequest;
155+
}
156+
157+
/**
158+
* Presign the provided HTTP request using SRA HttpSigner
159+
*/
160+
private SdkHttpFullRequest sraPresignRequest(ExecutionAttributes executionAttributes, SdkHttpFullRequest request,
161+
String signingRegion) {
162+
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
146163

147-
Aws4Signer signer = Aws4Signer.create();
148-
Aws4PresignerParams presignerParams = Aws4PresignerParams.builder()
149-
.signingRegion(Region.of(signingRegion))
150-
.signingName(SERVICE_NAME)
151-
.signingClockOverride(signingOverrideClock)
152-
.awsCredentials(resolveCredentials(attributes))
153-
.build();
154164

155-
return signer.presign(request, presignerParams);
165+
Instant signingInstant;
166+
if (signingClockOverride != null) {
167+
signingInstant = signingClockOverride.instant();
168+
} else {
169+
signingInstant = Instant.now();
170+
}
171+
// A fixed signing clock is used so that the current time used by the signing logic, as well as to
172+
// determine expiration are the same.
173+
Clock signingClock = Clock.fixed(signingInstant, ZoneOffset.UTC);
174+
Duration expirationDuration = Duration.ofDays(7);
175+
return doSraPresign(request, selectedAuthScheme, signingRegion, signingClock, expirationDuration);
176+
}
177+
178+
private <T extends Identity> SdkHttpFullRequest doSraPresign(SdkHttpFullRequest request,
179+
SelectedAuthScheme<T> selectedAuthScheme,
180+
String signingRegion,
181+
Clock signingClock,
182+
Duration expirationDuration) {
183+
CompletableFuture<? extends T> identityFuture = selectedAuthScheme.identity();
184+
T identity = CompletableFutureUtils.joinLikeSync(identityFuture);
185+
186+
// Pre-signed URL puts auth info in query string, does not sign the payload, and has an expiry.
187+
SignRequest.Builder<T> signRequestBuilder = SignRequest
188+
.builder(identity)
189+
.putProperty(AwsV4FamilyHttpSigner.AUTH_LOCATION, AwsV4FamilyHttpSigner.AuthLocation.QUERY_STRING)
190+
.putProperty(AwsV4FamilyHttpSigner.EXPIRATION_DURATION, expirationDuration)
191+
.putProperty(HttpSigner.SIGNING_CLOCK, signingClock)
192+
.request(request)
193+
.payload(request.contentStreamProvider().orElse(null));
194+
AuthSchemeOption authSchemeOption = selectedAuthScheme.authSchemeOption();
195+
authSchemeOption.forEachSignerProperty(signRequestBuilder::putProperty);
196+
// Override the region
197+
signRequestBuilder.putProperty(AwsV4HttpSigner.REGION_NAME, signingRegion);
198+
HttpSigner<T> signer = selectedAuthScheme.signer();
199+
SignedRequest signedRequest = signer.sign(signRequestBuilder.build());
200+
return toSdkHttpFullRequest(signedRequest);
156201
}
157202

158-
private AwsCredentials resolveCredentials(ExecutionAttributes attributes) {
159-
return attributes.getOptionalAttribute(SELECTED_AUTH_SCHEME)
160-
.map(selectedAuthScheme -> selectedAuthScheme.identity())
161-
.map(identityFuture -> CompletableFutureUtils.joinLikeSync(identityFuture))
162-
.filter(identity -> identity instanceof AwsCredentialsIdentity)
163-
.map(identity -> {
164-
AwsCredentialsIdentity awsCredentialsIdentity = (AwsCredentialsIdentity) identity;
165-
return CredentialUtils.toCredentials(awsCredentialsIdentity);
166-
}).orElse(attributes.getAttribute(AWS_CREDENTIALS));
203+
private SdkHttpFullRequest toSdkHttpFullRequest(SignedRequest signedRequest) {
204+
SdkHttpRequest request = signedRequest.request();
205+
206+
return SdkHttpFullRequest.builder()
207+
.contentStreamProvider(signedRequest.payload().orElse(null))
208+
.protocol(request.protocol())
209+
.method(request.method())
210+
.host(request.host())
211+
.port(request.port())
212+
.encodedPath(request.encodedPath())
213+
.applyMutation(r -> request.forEachHeader(r::putHeader))
214+
.applyMutation(r -> request.forEachRawQueryParameter(r::putRawQueryParameter))
215+
.removeQueryParameter(PARAM_SOURCE_REGION)
216+
.build();
167217
}
168218

169219
private URI createEndpoint(String regionName, String serviceName, ExecutionAttributes attributes) {
170220
Region region = Region.of(regionName);
171-
172221
if (region == null) {
173222
throw SdkClientException.builder()
174223
.message("{" + serviceName + ", " + regionName + "} was not "
175-
+ "found in region metadata. Update to latest version of SDK and try again.")
224+
+ "found in region metadata. Update to latest version of SDK and try again.")
176225
.build();
177226
}
178227

services/docdb/src/main/resources/codegen-resources/customization.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{
2+
"useSraAuth": true,
3+
"enableGenerateCompiledEndpointRules": true,
24
"verifiedSimpleMethods" : [
35
"describeDBClusterParameterGroups",
46
"describeDBClusterSnapshots",

0 commit comments

Comments
 (0)