Skip to content

Commit 9e3d3e3

Browse files
authored
Disable S3 payload signing. (#4499)
* Disable S3 payload signing. This is currently redundant, but when useSraAuth is made true, it will ensure that payload signing remains disabled. * Addressed comments
1 parent e5d7262 commit 9e3d3e3

File tree

3 files changed

+155
-1
lines changed

3 files changed

+155
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.services.s3.internal.handlers;
17+
18+
import software.amazon.awssdk.annotations.SdkInternalApi;
19+
import software.amazon.awssdk.auth.signer.S3SignerExecutionAttribute;
20+
import software.amazon.awssdk.core.interceptor.Context;
21+
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
22+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
23+
24+
/**
25+
* Disables payload signing for all S3 operations.
26+
*
27+
* <p>TODO(sra-identity-auth): After S3's migration to the SRA, we should use signer properties in the auth scheme resolver.
28+
*/
29+
@SdkInternalApi
30+
public class DisablePayloadSigningInterceptor implements ExecutionInterceptor {
31+
@Override
32+
public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
33+
executionAttributes.putAttributeIfAbsent(S3SignerExecutionAttribute.ENABLE_PAYLOAD_SIGNING, false);
34+
}
35+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,8 @@
256256
"software.amazon.awssdk.services.s3.internal.handlers.EnableTrailingChecksumInterceptor",
257257
"software.amazon.awssdk.services.s3.internal.handlers.ExceptionTranslationInterceptor",
258258
"software.amazon.awssdk.services.s3.internal.handlers.GetObjectInterceptor",
259-
"software.amazon.awssdk.services.s3.internal.handlers.CopySourceInterceptor"
259+
"software.amazon.awssdk.services.s3.internal.handlers.CopySourceInterceptor",
260+
"software.amazon.awssdk.services.s3.internal.handlers.DisablePayloadSigningInterceptor"
260261
],
261262
"requiredTraitValidationEnabled": true,
262263
"enableEndpointAuthSchemeParams": true,
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.services.s3;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import org.junit.jupiter.api.Test;
21+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
22+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
23+
import software.amazon.awssdk.auth.signer.S3SignerExecutionAttribute;
24+
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
25+
import software.amazon.awssdk.http.HttpExecuteResponse;
26+
import software.amazon.awssdk.http.SdkHttpResponse;
27+
import software.amazon.awssdk.regions.Region;
28+
import software.amazon.awssdk.testutils.service.http.MockAsyncHttpClient;
29+
import software.amazon.awssdk.testutils.service.http.MockSyncHttpClient;
30+
31+
/**
32+
* Ensure that payload signing is disabled for S3 operations.
33+
*/
34+
public class PayloadSigningDisabledTest {
35+
private static final AwsCredentialsProvider CREDENTIALS = () -> AwsBasicCredentials.create("akid", "skid");
36+
private static final ClientOverrideConfiguration ENABLE_PAYLOAD_SIGNING_CONFIG =
37+
ClientOverrideConfiguration.builder()
38+
.putExecutionAttribute(S3SignerExecutionAttribute.ENABLE_PAYLOAD_SIGNING, true)
39+
.build();
40+
41+
@Test
42+
public void syncPayloadSigningIsDisabled() {
43+
try (MockSyncHttpClient httpClient = new MockSyncHttpClient();
44+
S3Client s3 = S3Client.builder()
45+
.region(Region.US_WEST_2)
46+
.credentialsProvider(CREDENTIALS)
47+
.httpClient(httpClient)
48+
.build()) {
49+
httpClient.stubNextResponse(HttpExecuteResponse.builder()
50+
.response(SdkHttpResponse.builder().statusCode(200).build())
51+
.build());
52+
53+
s3.createBucket(r -> r.bucket("foo"));
54+
55+
assertThat(httpClient.getLastRequest().firstMatchingHeader("x-amz-content-sha256"))
56+
.hasValue("UNSIGNED-PAYLOAD");
57+
}
58+
}
59+
60+
@Test
61+
public void asyncPayloadSigningIsDisabled() {
62+
try (MockAsyncHttpClient httpClient = new MockAsyncHttpClient();
63+
S3AsyncClient s3 = S3AsyncClient.builder()
64+
.region(Region.US_WEST_2)
65+
.credentialsProvider(CREDENTIALS)
66+
.httpClient(httpClient)
67+
.build()) {
68+
httpClient.stubNextResponse(HttpExecuteResponse.builder()
69+
.response(SdkHttpResponse.builder().statusCode(200).build())
70+
.build());
71+
72+
s3.createBucket(r -> r.bucket("foo")).join();
73+
74+
assertThat(httpClient.getLastRequest().firstMatchingHeader("x-amz-content-sha256"))
75+
.hasValue("UNSIGNED-PAYLOAD");
76+
}
77+
}
78+
79+
@Test
80+
public void syncPayloadSigningCanBeEnabled() {
81+
try (MockSyncHttpClient httpClient = new MockSyncHttpClient();
82+
S3Client s3 = S3Client.builder()
83+
.region(Region.US_WEST_2)
84+
.credentialsProvider(CREDENTIALS)
85+
.httpClient(httpClient)
86+
.overrideConfiguration(ENABLE_PAYLOAD_SIGNING_CONFIG)
87+
.build()) {
88+
httpClient.stubNextResponse(HttpExecuteResponse.builder()
89+
.response(SdkHttpResponse.builder().statusCode(200).build())
90+
.build());
91+
92+
s3.createBucket(r -> r.bucket("foo"));
93+
94+
assertThat(httpClient.getLastRequest().firstMatchingHeader("x-amz-content-sha256"))
95+
.hasValue("a40ef303139635de59992f34c1c7da763f89200f2d55b71016f7c156527d63a0");
96+
}
97+
}
98+
99+
@Test
100+
public void asyncPayloadSigningCanBeEnabled() {
101+
try (MockAsyncHttpClient httpClient = new MockAsyncHttpClient();
102+
S3AsyncClient s3 = S3AsyncClient.builder()
103+
.region(Region.US_WEST_2)
104+
.credentialsProvider(CREDENTIALS)
105+
.httpClient(httpClient)
106+
.overrideConfiguration(ENABLE_PAYLOAD_SIGNING_CONFIG)
107+
.build()) {
108+
httpClient.stubNextResponse(HttpExecuteResponse.builder()
109+
.response(SdkHttpResponse.builder().statusCode(200).build())
110+
.build());
111+
112+
s3.createBucket(r -> r.bucket("foo")).join();
113+
114+
assertThat(httpClient.getLastRequest().firstMatchingHeader("x-amz-content-sha256"))
115+
.hasValue("a40ef303139635de59992f34c1c7da763f89200f2d55b71016f7c156527d63a0");
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)