From 16b7cae6710be5f497d156adc30e0a9a79b040e8 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Thu, 16 Sep 2021 14:17:48 -0400 Subject: [PATCH 1/9] !move credentials and signing into separate auth packages --- .../aws/sdk/kotlin/runtime/auth/AuthConfig.kt | 2 ++ .../CachedCredentialsProvider.kt | 2 +- .../auth/{ => credentials}/Credentials.kt | 2 +- .../{ => credentials}/CredentialsProvider.kt | 2 +- .../CrtBasedCredentialsProvider.kt | 2 +- .../auth/{ => credentials}/CrtCredentialUtils.kt | 2 +- .../DefaultChainCredentialsProvider.kt | 2 +- .../EnvironmentCredentialsProvider.kt | 2 +- .../ProfileCredentialsProvider.kt | 2 +- .../StaticCredentialsProvider.kt | 2 +- .../{ => signing}/AwsSigV4SigningMiddleware.kt | 4 +++- .../auth/{ => signing}/AwsSigningConfig.kt | 4 +++- .../runtime/auth/{ => signing}/Presigner.kt | 9 ++++++++- .../EnvironmentCredentialsProviderTest.kt | 2 +- .../StaticCredentialsProviderTest.kt | 2 +- .../AwsSigv4SigningMiddlewareTest.kt | 4 +++- .../ProfileCredentialsProviderJvm.kt | 2 +- .../ProfileCredentialsProviderTest.kt | 2 +- .../aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt | 16 ++++++++-------- .../sdk/kotlin/codegen/PresignerGeneratorTest.kt | 13 ++++++------- .../aws/sdk/kotlin/services/polly/PollyTest.kt | 2 +- 21 files changed, 47 insertions(+), 33 deletions(-) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/CachedCredentialsProvider.kt (98%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/Credentials.kt (85%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/CredentialsProvider.kt (87%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/CrtBasedCredentialsProvider.kt (89%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/CrtCredentialUtils.kt (95%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/DefaultChainCredentialsProvider.kt (95%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/EnvironmentCredentialsProvider.kt (95%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/ProfileCredentialsProvider.kt (97%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/StaticCredentialsProvider.kt (96%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => signing}/AwsSigV4SigningMiddleware.kt (97%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => signing}/AwsSigningConfig.kt (97%) rename aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/{ => signing}/Presigner.kt (94%) rename aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/{ => credentials}/EnvironmentCredentialsProviderTest.kt (97%) rename aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/{ => credentials}/StaticCredentialsProviderTest.kt (94%) rename aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/{ => signing}/AwsSigv4SigningMiddlewareTest.kt (97%) rename aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/{ => credentials}/ProfileCredentialsProviderJvm.kt (92%) rename aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/{ => credentials}/ProfileCredentialsProviderTest.kt (98%) diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AuthConfig.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AuthConfig.kt index 6a1c06f1f12..ca10df221b2 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AuthConfig.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AuthConfig.kt @@ -5,6 +5,8 @@ package aws.sdk.kotlin.runtime.auth +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider + /** * A common interface that all AWS service clients implement as part of their configuration state. */ diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CachedCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CachedCredentialsProvider.kt similarity index 98% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CachedCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CachedCredentialsProvider.kt index ab11d29a0c9..08d2216ae5f 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CachedCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CachedCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.crt.auth.credentials.build import kotlin.time.Duration diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Credentials.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/Credentials.kt similarity index 85% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Credentials.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/Credentials.kt index 64b11e45a56..5e1faec3660 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Credentials.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/Credentials.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials /** * Represents a set of AWS credentials diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CredentialsProvider.kt similarity index 87% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CredentialsProvider.kt index ea82222f6a6..b83ba58c8d7 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials /** * Represents a producer/source of AWS credentials diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtBasedCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtBasedCredentialsProvider.kt similarity index 89% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtBasedCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtBasedCredentialsProvider.kt index 15d85250742..a62ab5be194 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtBasedCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtBasedCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.crt.auth.credentials.CredentialsProvider as CredentialsProviderCrt diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtCredentialUtils.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtCredentialUtils.kt similarity index 95% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtCredentialUtils.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtCredentialUtils.kt index 517a8668360..f20bad94d61 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CrtCredentialUtils.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/CrtCredentialUtils.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.crt.auth.credentials.Credentials as CredentialsCrt import aws.sdk.kotlin.crt.auth.credentials.CredentialsProvider as CredentialsProviderCrt diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/DefaultChainCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/DefaultChainCredentialsProvider.kt similarity index 95% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/DefaultChainCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/DefaultChainCredentialsProvider.kt index f415768cdf6..475cdd298f7 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/DefaultChainCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/DefaultChainCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.crt.auth.credentials.build import aws.sdk.kotlin.runtime.crt.SdkDefaultIO diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProvider.kt similarity index 95% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProvider.kt index b6584026310..b5828c008e6 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.runtime.AwsSdkSetting import aws.sdk.kotlin.runtime.ConfigurationException diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProvider.kt similarity index 97% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProvider.kt index bd66197fdcd..be901d5a6f2 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.crt.auth.credentials.build import aws.sdk.kotlin.runtime.crt.SdkDefaultIO diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/StaticCredentialsProvider.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProvider.kt similarity index 96% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/StaticCredentialsProvider.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProvider.kt index bda6d3ebeda..a92661d7ca0 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/StaticCredentialsProvider.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProvider.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials /** * A credentials provider for a fixed set of credentials diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigV4SigningMiddleware.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt similarity index 97% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigV4SigningMiddleware.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt index 44441533ba2..37652bc5528 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigV4SigningMiddleware.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt @@ -3,13 +3,15 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyValue import aws.sdk.kotlin.crt.auth.signing.AwsSigner import aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm import aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig import aws.sdk.kotlin.runtime.InternalSdkApi +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider +import aws.sdk.kotlin.runtime.auth.credentials.toCrt import aws.sdk.kotlin.runtime.crt.toSignableCrtRequest import aws.sdk.kotlin.runtime.crt.update import aws.sdk.kotlin.runtime.execution.AuthAttributes diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigningConfig.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt similarity index 97% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigningConfig.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt index 5cde171abc3..b82af658e08 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/AwsSigningConfig.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt @@ -3,9 +3,11 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.runtime.InternalSdkApi +import aws.sdk.kotlin.runtime.auth.credentials.Credentials +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.smithy.kotlin.runtime.time.Instant import kotlin.time.Duration import kotlin.time.ExperimentalTime diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Presigner.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/Presigner.kt similarity index 94% rename from aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Presigner.kt rename to aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/Presigner.kt index f39f768748e..4cef073990c 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/Presigner.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/Presigner.kt @@ -1,10 +1,17 @@ -package aws.sdk.kotlin.runtime.auth +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.crt.auth.signing.AwsSignatureType import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyHeaderType import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyValue import aws.sdk.kotlin.crt.auth.signing.AwsSigner import aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider +import aws.sdk.kotlin.runtime.auth.credentials.toCrt import aws.sdk.kotlin.runtime.crt.path import aws.sdk.kotlin.runtime.crt.queryParameters import aws.sdk.kotlin.runtime.crt.toCrtHeaders diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProviderTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProviderTest.kt similarity index 97% rename from aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProviderTest.kt rename to aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProviderTest.kt index 0a75340ea66..7e7ea50d07c 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProviderTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/EnvironmentCredentialsProviderTest.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.runtime.AwsSdkSetting import aws.sdk.kotlin.runtime.ConfigurationException diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/StaticCredentialsProviderTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProviderTest.kt similarity index 94% rename from aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/StaticCredentialsProviderTest.kt rename to aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProviderTest.kt index 6d8b367a7b4..9aa809d1014 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/StaticCredentialsProviderTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/credentials/StaticCredentialsProviderTest.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.runtime.testing.runSuspendTest import kotlin.test.Test diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/AwsSigv4SigningMiddlewareTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt similarity index 97% rename from aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/AwsSigv4SigningMiddlewareTest.kt rename to aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt index 2d331a096b4..d64f812fe91 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/AwsSigv4SigningMiddlewareTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt @@ -3,8 +3,10 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.signing +import aws.sdk.kotlin.runtime.auth.credentials.Credentials +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.sdk.kotlin.runtime.execution.AuthAttributes import aws.sdk.kotlin.runtime.testing.runSuspendTest import aws.smithy.kotlin.runtime.client.ExecutionContext diff --git a/aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderJvm.kt b/aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderJvm.kt similarity index 92% rename from aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderJvm.kt rename to aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderJvm.kt index aba4a518349..b8b0853edbf 100644 --- a/aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderJvm.kt +++ b/aws-runtime/auth/jvm/src/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderJvm.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.runtime.AwsSdkSetting diff --git a/aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderTest.kt b/aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderTest.kt similarity index 98% rename from aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderTest.kt rename to aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderTest.kt index 1e9ee142abe..1b37dc6a89c 100644 --- a/aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/ProfileCredentialsProviderTest.kt +++ b/aws-runtime/auth/jvm/test/aws/sdk/kotlin/runtime/auth/credentials/ProfileCredentialsProviderTest.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -package aws.sdk.kotlin.runtime.auth +package aws.sdk.kotlin.runtime.auth.credentials import aws.sdk.kotlin.runtime.AwsSdkSetting import io.kotest.extensions.system.withEnvironment diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt index 725e90432d3..2e3d9298a75 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt @@ -38,14 +38,14 @@ object AwsRuntimeTypes { } object Auth { - val AwsSigV4SigningMiddleware = runtimeSymbol("AwsSigV4SigningMiddleware", AwsKotlinDependency.AWS_AUTH) - val AwsSignedBodyHeaderType = runtimeSymbol("AwsSignedBodyHeaderType", AwsKotlinDependency.AWS_AUTH) - val CredentialsProvider = runtimeSymbol("CredentialsProvider", AwsKotlinDependency.AWS_AUTH) - val createPresignedRequest = runtimeSymbol("createPresignedRequest", AwsKotlinDependency.AWS_AUTH) - val DefaultChainCredentialsProvider = runtimeSymbol("DefaultChainCredentialsProvider", AwsKotlinDependency.AWS_AUTH) - val PresignedRequestConfig = runtimeSymbol("PresignedRequestConfig", AwsKotlinDependency.AWS_AUTH) - val ServicePresignConfig = runtimeSymbol("ServicePresignConfig", AwsKotlinDependency.AWS_AUTH) - val SigningLocation = runtimeSymbol("SigningLocation", AwsKotlinDependency.AWS_AUTH) + val AwsSigV4SigningMiddleware = runtimeSymbol("AwsSigV4SigningMiddleware", AwsKotlinDependency.AWS_AUTH, "signing") + val AwsSignedBodyHeaderType = runtimeSymbol("AwsSignedBodyHeaderType", AwsKotlinDependency.AWS_AUTH, "signing") + val CredentialsProvider = runtimeSymbol("CredentialsProvider", AwsKotlinDependency.AWS_AUTH, "credentials") + val createPresignedRequest = runtimeSymbol("createPresignedRequest", AwsKotlinDependency.AWS_AUTH, "signing") + val DefaultChainCredentialsProvider = runtimeSymbol("DefaultChainCredentialsProvider", AwsKotlinDependency.AWS_AUTH, "credentials") + val PresignedRequestConfig = runtimeSymbol("PresignedRequestConfig", AwsKotlinDependency.AWS_AUTH, "signing") + val ServicePresignConfig = runtimeSymbol("ServicePresignConfig", AwsKotlinDependency.AWS_AUTH, "signing") + val SigningLocation = runtimeSymbol("SigningLocation", AwsKotlinDependency.AWS_AUTH, "signing") } object Regions { diff --git a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt index c52a4039a65..bf44e96d847 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt @@ -86,13 +86,12 @@ class PresignerGeneratorTest { val expected = """ package smithy.kotlin.traits - import aws.sdk.kotlin.runtime.ClientException - import aws.sdk.kotlin.runtime.auth.CredentialsProvider - import aws.sdk.kotlin.runtime.auth.DefaultChainCredentialsProvider - import aws.sdk.kotlin.runtime.auth.PresignedRequestConfig - import aws.sdk.kotlin.runtime.auth.ServicePresignConfig - import aws.sdk.kotlin.runtime.auth.SigningLocation - import aws.sdk.kotlin.runtime.auth.createPresignedRequest + import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider + import aws.sdk.kotlin.runtime.auth.credentials.DefaultChainCredentialsProvider + import aws.sdk.kotlin.runtime.auth.signing.PresignedRequestConfig + import aws.sdk.kotlin.runtime.auth.signing.ServicePresignConfig + import aws.sdk.kotlin.runtime.auth.signing.SigningLocation + import aws.sdk.kotlin.runtime.auth.signing.createPresignedRequest import aws.sdk.kotlin.runtime.endpoint.EndpointResolver import aws.smithy.kotlin.runtime.client.ExecutionContext import aws.smithy.kotlin.runtime.http.QueryParameters diff --git a/services/polly/common/test/aws/sdk/kotlin/services/polly/PollyTest.kt b/services/polly/common/test/aws/sdk/kotlin/services/polly/PollyTest.kt index 31df18bc4aa..c2bfe958c20 100644 --- a/services/polly/common/test/aws/sdk/kotlin/services/polly/PollyTest.kt +++ b/services/polly/common/test/aws/sdk/kotlin/services/polly/PollyTest.kt @@ -1,6 +1,6 @@ package aws.sdk.kotlin.services.polly -import aws.sdk.kotlin.runtime.auth.StaticCredentialsProvider +import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider import aws.sdk.kotlin.runtime.testing.runSuspendTest import aws.sdk.kotlin.services.polly.model.OutputFormat import aws.sdk.kotlin.services.polly.model.SynthesizeSpeechRequest From e9ff041bf06b80289787ce6b0bfca427710e7b42 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Fri, 17 Sep 2021 10:34:04 -0400 Subject: [PATCH 2/9] add sigva algorithm and add sign() function --- .../auth/signing/AwsSigV4SigningMiddleware.kt | 17 ++-- .../kotlin/runtime/auth/signing/AwsSigning.kt | 49 +++++++++++ .../runtime/auth/signing/AwsSigningConfig.kt | 66 ++++++++++++++- .../runtime/auth/signing/AwsSigningTest.kt | 83 +++++++++++++++++++ .../signing/AwsSigv4SigningMiddlewareTest.kt | 7 -- .../runtime/auth/signing/SigningTestUtil.kt | 14 ++++ .../src/aws/sdk/kotlin/runtime/crt/Http.kt | 39 ++++++--- 7 files changed, 243 insertions(+), 32 deletions(-) create mode 100644 aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt create mode 100644 aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigningTest.kt create mode 100644 aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/SigningTestUtil.kt diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt index 37652bc5528..da2d02b9fa1 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt @@ -7,11 +7,8 @@ package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyValue import aws.sdk.kotlin.crt.auth.signing.AwsSigner -import aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm -import aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig import aws.sdk.kotlin.runtime.InternalSdkApi import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider -import aws.sdk.kotlin.runtime.auth.credentials.toCrt import aws.sdk.kotlin.runtime.crt.toSignableCrtRequest import aws.sdk.kotlin.runtime.crt.update import aws.sdk.kotlin.runtime.execution.AuthAttributes @@ -20,7 +17,6 @@ import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.operation.SdkHttpOperation import aws.smithy.kotlin.runtime.http.operation.withContext import aws.smithy.kotlin.runtime.logging.Logger -import aws.smithy.kotlin.runtime.time.epochMilliseconds import aws.smithy.kotlin.runtime.util.get /** @@ -119,19 +115,19 @@ public class AwsSigV4SigningMiddleware internal constructor(private val config: // then we must decide how to compute the payload hash ourselves (defaults to unsigned payload) val isUnboundedStream = signableRequest.body == null && req.subject.body is HttpBody.Streaming - val signingConfig: AwsSigningConfig = AwsSigningConfig.build { + val signingConfig = AwsSigningConfig { region = req.context[AuthAttributes.SigningRegion] service = req.context.getOrNull(AuthAttributes.SigningService) ?: checkNotNull(config.signingService) - credentials = resolvedCredentials.toCrt() + credentials = resolvedCredentials algorithm = AwsSigningAlgorithm.SIGV4 - date = req.context.getOrNull(AuthAttributes.SigningDate)?.epochMilliseconds + date = req.context.getOrNull(AuthAttributes.SigningDate) - signatureType = config.signatureType.toCrt() + signatureType = config.signatureType omitSessionToken = config.omitSessionToken normalizeUriPath = config.normalizeUriPath useDoubleUriEncode = config.useDoubleUriEncode - signedBodyHeader = config.signedBodyHeaderType.toCrt() + signedBodyHeader = config.signedBodyHeaderType signedBodyValue = when { isUnsignedRequest -> AwsSignedBodyValue.UNSIGNED_PAYLOAD req.subject.body is HttpBody.Empty -> AwsSignedBodyValue.EMPTY_SHA256 @@ -143,7 +139,8 @@ public class AwsSigV4SigningMiddleware internal constructor(private val config: else -> null } } - val signedRequest = AwsSigner.signRequest(signableRequest, signingConfig) + + val signedRequest = AwsSigner.signRequest(signableRequest, signingConfig.toCrt()) req.subject.update(signedRequest) req.subject.body.resetStream() diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt new file mode 100644 index 00000000000..8cb0408730b --- /dev/null +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt @@ -0,0 +1,49 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package aws.sdk.kotlin.runtime.auth.signing + +import aws.sdk.kotlin.crt.auth.signing.AwsSigner +import aws.sdk.kotlin.runtime.crt.toSignableCrtRequest +import aws.sdk.kotlin.runtime.crt.update +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.request.toBuilder + +/** + * Container for signed output and signature + */ +public data class SigningResult(val output: T, val signature: ByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as SigningResult<*> + + if (output != other.output) return false + if (!signature.contentEquals(other.signature)) return false + + return true + } + + override fun hashCode(): Int { + var result = output?.hashCode() ?: 0 + result = 31 * result + signature.contentHashCode() + return result + } +} + +/** + * Sign [HttpRequest] using the given signing [config] + * @return signing result + */ +public suspend fun sign(request: HttpRequest, config: AwsSigningConfig): SigningResult { + val crtRequest = request.toSignableCrtRequest() + val crtResult = AwsSigner.sign(crtRequest, config.toCrt()) + val crtSignedRequest = checkNotNull(crtResult.signedRequest) { "Signed request unexpectedly null" } + val builder = request.toBuilder() + builder.update(crtSignedRequest) + val output = builder.build() + return SigningResult(output, crtResult.signature) +} diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt index b82af658e08..22ba9f7eb73 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigningConfig.kt @@ -5,18 +5,23 @@ package aws.sdk.kotlin.runtime.auth.signing -import aws.sdk.kotlin.runtime.InternalSdkApi import aws.sdk.kotlin.runtime.auth.credentials.Credentials import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider +import aws.sdk.kotlin.runtime.auth.credentials.toCrt import aws.smithy.kotlin.runtime.time.Instant +import aws.smithy.kotlin.runtime.time.epochMilliseconds import kotlin.time.Duration import kotlin.time.ExperimentalTime +/** + * Predicate function used to determine if a specific header should be signed or not + */ +public typealias ShouldSignHeaderFn = (String) -> Boolean + /** * Configuration that tells the underlying AWS signer how to sign requests */ @OptIn(ExperimentalTime::class) -@InternalSdkApi public class AwsSigningConfig private constructor(builder: Builder) { public companion object { public operator fun invoke(block: Builder.() -> Unit): AwsSigningConfig = Builder().apply(block).build() @@ -80,6 +85,11 @@ public class AwsSigningConfig private constructor(builder: Builder) { */ public val signedBodyHeaderType: AwsSignedBodyHeaderType = builder.signedBodyHeader + /** + * Predicate function used to determine if a specific header should be signed or not + */ + public val shouldSignHeader: ShouldSignHeaderFn? = builder.shouldSignHeader + /* * Signing key control: * @@ -117,6 +127,7 @@ public class AwsSigningConfig private constructor(builder: Builder) { public var service: String? = null public var date: Instant? = null public var algorithm: AwsSigningAlgorithm = AwsSigningAlgorithm.SIGV4 + public var shouldSignHeader: ShouldSignHeaderFn? = null public var signatureType: AwsSignatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS public var useDoubleUriEncode: Boolean = true public var normalizeUriPath: Boolean = true @@ -142,7 +153,12 @@ public enum class AwsSigningAlgorithm { * AWS Signature Version 4 * see: https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html */ - SIGV4; + SIGV4, + + /** + * AWS Signature Version 4 Asymmetric + */ + SIGV4_ASYMMETRIC; } /** @@ -185,6 +201,18 @@ public enum class AwsSignedBodyHeaderType { X_AMZ_CONTENT_SHA256; } +/** + * A set of string constants for various canonical request payload values. If signedBodyValue is not null + * then the value will also be reflected in X-Amz-Content-Sha256 + */ +public object AwsSignedBodyValue { + public const val EMPTY_SHA256: String = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + public const val UNSIGNED_PAYLOAD: String = "UNSIGNED-PAYLOAD" + public const val STREAMING_AWS4_HMAC_SHA256_PAYLOAD: String = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" + public const val STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD: String = "STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD" + public const val STREAMING_AWS4_HMAC_SHA256_EVENTS: String = "STREAMING-AWS4-HMAC-SHA256-EVENTS" +} + internal fun AwsSignedBodyHeaderType.toCrt(): aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyHeaderType = when (this) { AwsSignedBodyHeaderType.NONE -> aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyHeaderType.NONE AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256 -> aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256 @@ -199,4 +227,36 @@ internal fun AwsSignatureType.toCrt(): aws.sdk.kotlin.crt.auth.signing.AwsSignat internal fun AwsSigningAlgorithm.toCrt(): aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm = when (this) { AwsSigningAlgorithm.SIGV4 -> aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm.SIGV4 + AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm.SIGV4_ASYMMETRIC +} + +@OptIn(ExperimentalTime::class) +internal suspend fun AwsSigningConfig.toCrt(): aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig { + val config = this + // NOTE: we cannot pass a credentialsProvider due to https://github.com/awslabs/aws-crt-kotlin/issues/15 + // the underlying implementation will hang/fail to sign + val resolvedCredentials = config.credentials ?: config.credentialsProvider?.getCredentials() + + return aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig.build { + algorithm = config.algorithm.toCrt() + credentials = resolvedCredentials?.toCrt() + + date = config.date?.epochMilliseconds + + config.expiresAfter?.let { + expirationInSeconds = it.inWholeSeconds + } + + normalizeUriPath = config.normalizeUriPath + omitSessionToken = config.omitSessionToken + + region = config.region + service = config.service + + shouldSignHeader = config.shouldSignHeader + signatureType = config.signatureType.toCrt() + signedBodyHeader = config.signedBodyHeaderType.toCrt() + signedBodyValue = config.signedBodyValue + useDoubleUriEncode = config.useDoubleUriEncode + } } diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigningTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigningTest.kt new file mode 100644 index 00000000000..7e2b41bda4d --- /dev/null +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigningTest.kt @@ -0,0 +1,83 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package aws.sdk.kotlin.runtime.auth.signing + +import aws.sdk.kotlin.runtime.testing.runSuspendTest +import aws.smithy.kotlin.runtime.http.HttpMethod +import aws.smithy.kotlin.runtime.http.content.ByteArrayContent +import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder +import aws.smithy.kotlin.runtime.time.Instant +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class AwsSigningTest { + + @Test + fun testSignRequestSigV4() = runSuspendTest { + // sanity test + val request = HttpRequestBuilder().apply { + method = HttpMethod.POST + url.host = "http://demo.us-east-1.amazonaws.com" + url.path = "/" + headers.append("Host", "demo.us-east-1.amazonaws.com") + headers.appendAll("x-amz-archive-description", listOf("test", "test")) + val requestBody = "{\"TableName\": \"foo\"}" + body = ByteArrayContent(requestBody.encodeToByteArray()) + headers.append("Content-Length", body.contentLength?.toString() ?: "0") + }.build() + + val config = AwsSigningConfig { + region = "us-east-1" + service = "demo" + signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS + date = Instant.fromIso8601("2020-10-16T19:56:00Z") + credentialsProvider = TestCredentialsProvider + } + + val result = sign(request, config) + + val expectedDate = "20201016T195600Z" + val expectedSig = "e60a4adad4ae15e05c96a0d8ac2482fbcbd66c88647c4457db74e4dad1648608" + val expectedAuth = "AWS4-HMAC-SHA256 Credential=AKID/20201016/us-east-1/demo/aws4_request, " + + "SignedHeaders=content-length;host;x-amz-archive-description;x-amz-date;x-amz-security-token, " + + "Signature=$expectedSig" + + assertEquals(expectedDate, result.output.headers["X-Amz-Date"]) + assertEquals(expectedAuth, result.output.headers["Authorization"]) + assertEquals(expectedSig, result.signature.decodeToString()) + } + + @Test + fun testSignRequestSigV4Asymmetric() = runSuspendTest { + // sanity test + val request = HttpRequestBuilder().apply { + method = HttpMethod.POST + url.host = "http://demo.us-east-1.amazonaws.com" + url.path = "/" + headers.append("Host", "demo.us-east-1.amazonaws.com") + headers.appendAll("x-amz-archive-description", listOf("test", "test")) + val requestBody = "{\"TableName\": \"foo\"}" + body = ByteArrayContent(requestBody.encodeToByteArray()) + headers.append("Content-Length", body.contentLength?.toString() ?: "0") + }.build() + + val config = AwsSigningConfig { + region = "us-east-1" + service = "service" + signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS + algorithm = AwsSigningAlgorithm.SIGV4_ASYMMETRIC + date = Instant.fromIso8601("2015-08-30T12:36:00Z") + credentialsProvider = TestCredentialsProvider + } + + val result = sign(request, config) + + val expectedPrefix = "AWS4-ECDSA-P256-SHA256 Credential=AKID/20150830/service/aws4_request, SignedHeaders=content-length;host;x-amz-archive-description;x-amz-date;x-amz-region-set;x-amz-security-token, Signature=" + val authHeader = result.output.headers["Authorization"]!! + assertTrue(authHeader.contains(expectedPrefix), "Sigv4A auth header: $authHeader") + } +} diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt index d64f812fe91..4612c55ee5f 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt @@ -5,8 +5,6 @@ package aws.sdk.kotlin.runtime.auth.signing -import aws.sdk.kotlin.runtime.auth.credentials.Credentials -import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.sdk.kotlin.runtime.execution.AuthAttributes import aws.sdk.kotlin.runtime.testing.runSuspendTest import aws.smithy.kotlin.runtime.client.ExecutionContext @@ -26,11 +24,6 @@ import kotlin.test.assertEquals class AwsSigv4SigningMiddlewareTest { - private object TestCredentialsProvider : CredentialsProvider { - val testCredentials = Credentials("AKID", "SECRET", "SESSION") - override suspend fun getCredentials(): Credentials = testCredentials - } - private fun buildOperation(streaming: Boolean = false, replayable: Boolean = true): SdkHttpOperation = SdkHttpOperation.build { serializer = object : HttpSerialize { override suspend fun serialize(context: ExecutionContext, input: Unit): HttpRequestBuilder = diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/SigningTestUtil.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/SigningTestUtil.kt new file mode 100644 index 00000000000..b32dcc7cae4 --- /dev/null +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/SigningTestUtil.kt @@ -0,0 +1,14 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package aws.sdk.kotlin.runtime.auth.signing + +import aws.sdk.kotlin.runtime.auth.credentials.Credentials +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider + +object TestCredentialsProvider : CredentialsProvider { + val testCredentials = Credentials("AKID", "SECRET", "SESSION") + override suspend fun getCredentials(): Credentials = testCredentials +} diff --git a/aws-runtime/crt-util/common/src/aws/sdk/kotlin/runtime/crt/Http.kt b/aws-runtime/crt-util/common/src/aws/sdk/kotlin/runtime/crt/Http.kt index 670ad697dc2..742180edffe 100644 --- a/aws-runtime/crt-util/common/src/aws/sdk/kotlin/runtime/crt/Http.kt +++ b/aws-runtime/crt-util/common/src/aws/sdk/kotlin/runtime/crt/Http.kt @@ -8,6 +8,7 @@ package aws.sdk.kotlin.runtime.crt import aws.sdk.kotlin.crt.http.HttpRequestBodyStream import aws.sdk.kotlin.runtime.InternalSdkApi import aws.smithy.kotlin.runtime.http.* +import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.http.util.splitAsQueryParameters import kotlin.coroutines.coroutineContext @@ -24,18 +25,7 @@ public suspend fun HttpRequestBuilder.toSignableCrtRequest(unsignedPayload: Bool // see: https://github.com/awslabs/smithy-kotlin/issues/296 val bodyStream = if (!unsignedPayload) { - when (val httpBody = body) { - is HttpBody.Bytes -> HttpRequestBodyStream.fromByteArray(httpBody.bytes()) - is HttpBody.Streaming -> if (httpBody.isReplayable) { - // FIXME: this is not particularly efficient since we have to launch a coroutine to fill it. - // see https://github.com/awslabs/smithy-kotlin/issues/436 - ReadChannelBodyStream(httpBody.readFrom(), coroutineContext) - } else { - // can only consume the stream once - null - } - else -> null - } + signableBodyStream(body) } else { null } @@ -43,6 +33,31 @@ public suspend fun HttpRequestBuilder.toSignableCrtRequest(unsignedPayload: Bool return HttpRequestCrt(method.name, url.encodedPath, HttpHeadersCrt(headers), bodyStream) } +private suspend fun signableBodyStream(body: HttpBody): HttpRequestBodyStream? = when (body) { + is HttpBody.Bytes -> HttpRequestBodyStream.fromByteArray(body.bytes()) + is HttpBody.Streaming -> if (body.isReplayable) { + // FIXME: this is not particularly efficient since we have to launch a coroutine to fill it. + // see https://github.com/awslabs/smithy-kotlin/issues/436 + ReadChannelBodyStream(body.readFrom(), coroutineContext) + } else { + // can only consume the stream once + null + } + else -> null +} + +/** + * Convert an [HttpRequest] into a CRT HttpRequest for the purposes of signing + */ +@InternalSdkApi +public suspend fun HttpRequest.toSignableCrtRequest(): HttpRequestCrt = + HttpRequestCrt( + method = method.name, + encodedPath = url.encodedPath, + headers = headers.toCrtHeaders(), + body = signableBodyStream(body) + ) + // proxy the smithy-client-rt version of Headers to CRT (which is based on our client-rt version in the first place) private class HttpHeadersCrt(val headers: HeadersBuilder) : HeadersCrt { override fun contains(name: String): Boolean = headers.contains(name) From 9505cd6c4cb4b83603c06ed0952a7f80ed4e15ee Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Fri, 17 Sep 2021 10:48:57 -0400 Subject: [PATCH 3/9] refactor!: make middleware reuse signing config --- .../auth/signing/AwsSigV4SigningMiddleware.kt | 83 +++++-------------- .../signing/AwsSigv4SigningMiddlewareTest.kt | 2 +- .../middleware/AwsSignatureVersion4.kt | 4 +- .../kotlin/codegen/PresignerGeneratorTest.kt | 1 + 4 files changed, 27 insertions(+), 63 deletions(-) diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt index da2d02b9fa1..e19df655694 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt @@ -8,7 +8,6 @@ package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyValue import aws.sdk.kotlin.crt.auth.signing.AwsSigner import aws.sdk.kotlin.runtime.InternalSdkApi -import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.sdk.kotlin.runtime.crt.toSignableCrtRequest import aws.sdk.kotlin.runtime.crt.update import aws.sdk.kotlin.runtime.execution.AuthAttributes @@ -23,61 +22,24 @@ import aws.smithy.kotlin.runtime.util.get * HTTP request pipeline middleware that signs outgoing requests */ @InternalSdkApi -public class AwsSigV4SigningMiddleware internal constructor(private val config: Config) : Feature { - - public class Config { - /** - * The credentials provider used to sign requests with - */ - public var credentialsProvider: CredentialsProvider? = null - - /** - * The credential scope service name to sign requests for - * NOTE: The operation context is favored when [AuthAttributes.SigningService] is set - */ - public var signingService: String? = null - - /** - * Sets what signature should be computed - */ - public var signatureType: AwsSignatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS - - /** - * The uri is assumed to be encoded once in preparation for transmission. Certain services - * do not decode before checking signature, requiring double-encoding the uri in the canonical - * request in order to pass a signature check. - */ - public var useDoubleUriEncode: Boolean = true - - /** - * Controls whether or not the uri paths should be normalized when building the canonical request - */ - public var normalizeUriPath: Boolean = true - - /** - * Flag indicating if the "X-Amz-Security-Token" query param should be omitted. - * Normally, this parameter is added during signing if the credentials have a session token. - * The only known case where this should be true is when signing a websocket handshake to IoT Core. - */ - public var omitSessionToken: Boolean = false - - /** - * Controls what body "hash" header, if any, should be added to the canonical request and the signed request. - * Most services do not require this additional header. - */ - public var signedBodyHeaderType: AwsSignedBodyHeaderType = AwsSignedBodyHeaderType.NONE - } +public class AwsSigV4SigningMiddleware internal constructor(private val baseConfig: AwsSigningConfig) : Feature { - public companion object Feature : HttpClientFeatureFactory { + public companion object Feature : HttpClientFeatureFactory { private val logger = Logger.getLogger() override val key: FeatureKey = FeatureKey("AwsSigv4SigningMiddleware") - override fun create(block: Config.() -> Unit): AwsSigV4SigningMiddleware { - val config = Config().apply(block) + override fun create(block: AwsSigningConfig.Builder.() -> Unit): AwsSigV4SigningMiddleware { + val builder = AwsSigningConfig.Builder().apply(block) + + // region is required when using a standalone signing config but the middleware takes the signing region + // (and other settings) from the operation execution attributes and combines them with the middleware + // defaults + if (builder.region == null) { builder.region = "" } + val config = builder.build() - requireNotNull(config.credentialsProvider) { "AwsSigv4Signer requires a credentialsProvider" } - requireNotNull(config.signingService) { "AwsSigv4Signer requires a signing service" } + requireNotNull(config.credentialsProvider) { "AwsSigv4SigningMiddleware requires a credentialsProvider" } + requireNotNull(config.service) { "AwsSigv4SigningMiddleware requires a signing service" } return AwsSigV4SigningMiddleware(config) } @@ -86,7 +48,7 @@ public class AwsSigV4SigningMiddleware internal constructor(private val config: override fun install(operation: SdkHttpOperation) { operation.execution.finalize.intercept { req, next -> - val credentialsProvider = checkNotNull(config.credentialsProvider) + val credentialsProvider = checkNotNull(baseConfig.credentialsProvider) val resolvedCredentials = credentialsProvider.getCredentials() val logger: Logger by lazy { logger.withContext(req.context) } @@ -115,19 +77,20 @@ public class AwsSigV4SigningMiddleware internal constructor(private val config: // then we must decide how to compute the payload hash ourselves (defaults to unsigned payload) val isUnboundedStream = signableRequest.body == null && req.subject.body is HttpBody.Streaming - val signingConfig = AwsSigningConfig { + // operation signing config is baseConfig + operation specific config/overrides + val opSigningConfig = AwsSigningConfig { region = req.context[AuthAttributes.SigningRegion] - service = req.context.getOrNull(AuthAttributes.SigningService) ?: checkNotNull(config.signingService) + service = req.context.getOrNull(AuthAttributes.SigningService) ?: checkNotNull(baseConfig.service) credentials = resolvedCredentials - algorithm = AwsSigningAlgorithm.SIGV4 + algorithm = baseConfig.algorithm date = req.context.getOrNull(AuthAttributes.SigningDate) - signatureType = config.signatureType - omitSessionToken = config.omitSessionToken - normalizeUriPath = config.normalizeUriPath - useDoubleUriEncode = config.useDoubleUriEncode + signatureType = baseConfig.signatureType + omitSessionToken = baseConfig.omitSessionToken + normalizeUriPath = baseConfig.normalizeUriPath + useDoubleUriEncode = baseConfig.useDoubleUriEncode - signedBodyHeader = config.signedBodyHeaderType + signedBodyHeader = baseConfig.signedBodyHeaderType signedBodyValue = when { isUnsignedRequest -> AwsSignedBodyValue.UNSIGNED_PAYLOAD req.subject.body is HttpBody.Empty -> AwsSignedBodyValue.EMPTY_SHA256 @@ -140,7 +103,7 @@ public class AwsSigV4SigningMiddleware internal constructor(private val config: } } - val signedRequest = AwsSigner.signRequest(signableRequest, signingConfig.toCrt()) + val signedRequest = AwsSigner.signRequest(signableRequest, opSigningConfig.toCrt()) req.subject.update(signedRequest) req.subject.body.resetStream() diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt index 4612c55ee5f..d6c62c90790 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt @@ -69,7 +69,7 @@ class AwsSigv4SigningMiddlewareTest { operation.install(AwsSigV4SigningMiddleware) { credentialsProvider = TestCredentialsProvider - signingService = "demo" + service = "demo" } operation.roundTrip(client, Unit) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt index c758ddbb190..eb35364bf53 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt @@ -43,8 +43,8 @@ open class AwsSignatureVersion4(private val signingServiceName: String) : HttpFe writer.addImport(AwsRuntimeTypes.Auth.AwsSigV4SigningMiddleware) writer.addImport("DefaultChainCredentialsProvider", AwsKotlinDependency.AWS_AUTH) - writer.write("credentialsProvider = config.credentialsProvider ?: DefaultChainCredentialsProvider()") - writer.write("signingService = #S", signingServiceName) + writer.write("this.credentialsProvider = config.credentialsProvider ?: DefaultChainCredentialsProvider()") + writer.write("this.service = #S", signingServiceName) } companion object { diff --git a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt index bf44e96d847..78aebfe4bbc 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt @@ -86,6 +86,7 @@ class PresignerGeneratorTest { val expected = """ package smithy.kotlin.traits + import aws.sdk.kotlin.runtime.ClientException import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.sdk.kotlin.runtime.auth.credentials.DefaultChainCredentialsProvider import aws.sdk.kotlin.runtime.auth.signing.PresignedRequestConfig From 181c62d732f54a768f4a0cdafb310ba9ed70f7e8 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Fri, 17 Sep 2021 12:01:17 -0400 Subject: [PATCH 4/9] fix codegen imports --- .../aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt | 2 ++ .../kotlin/codegen/AwsServiceConfigIntegration.kt | 5 +---- .../aws/sdk/kotlin/codegen/PresignerGenerator.kt | 2 +- .../protocols/middleware/AwsSignatureVersion4.kt | 3 +-- .../AwsHttpProtocolUnitTestRequestGenerator.kt | 13 +++---------- .../sdk/kotlin/codegen/PresignerGeneratorTest.kt | 2 +- 6 files changed, 9 insertions(+), 18 deletions(-) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt index 2e3d9298a75..6c42a30f57e 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt @@ -41,6 +41,8 @@ object AwsRuntimeTypes { val AwsSigV4SigningMiddleware = runtimeSymbol("AwsSigV4SigningMiddleware", AwsKotlinDependency.AWS_AUTH, "signing") val AwsSignedBodyHeaderType = runtimeSymbol("AwsSignedBodyHeaderType", AwsKotlinDependency.AWS_AUTH, "signing") val CredentialsProvider = runtimeSymbol("CredentialsProvider", AwsKotlinDependency.AWS_AUTH, "credentials") + val Credentials = runtimeSymbol("Credentials", AwsKotlinDependency.AWS_AUTH, "credentials") + val StaticCredentialsProvider = runtimeSymbol("StaticCredentialsProvider", AwsKotlinDependency.AWS_AUTH, "credentials") val createPresignedRequest = runtimeSymbol("createPresignedRequest", AwsKotlinDependency.AWS_AUTH, "signing") val DefaultChainCredentialsProvider = runtimeSymbol("DefaultChainCredentialsProvider", AwsKotlinDependency.AWS_AUTH, "credentials") val PresignedRequestConfig = runtimeSymbol("PresignedRequestConfig", AwsKotlinDependency.AWS_AUTH, "signing") diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsServiceConfigIntegration.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsServiceConfigIntegration.kt index 3cc548cac38..75db7a8f68a 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsServiceConfigIntegration.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsServiceConfigIntegration.kt @@ -61,10 +61,7 @@ class AwsServiceConfigIntegration : KotlinIntegration { ) CredentialsProviderProp = ClientConfigProperty { - symbol = buildSymbol { - name = "CredentialsProvider" - namespace(AwsKotlinDependency.AWS_AUTH) - } + symbol = AwsRuntimeTypes.Auth.CredentialsProvider baseClass = authConfigSymbol documentation = """ The AWS credentials provider to use for authenticating requests. If not provided a diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/PresignerGenerator.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/PresignerGenerator.kt index fd9a4a014d5..aeadb1da3f4 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/PresignerGenerator.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/PresignerGenerator.kt @@ -197,7 +197,7 @@ class PresignerGenerator : KotlinIntegration { nullable = false } name = "credentialsProvider" - documentation = "The AWS credentials provider to use for authenticating requests. If not provided a [aws.sdk.kotlin.runtime.auth.DefaultChainCredentialsProvider] instance will be used." + documentation = "The AWS credentials provider to use for authenticating requests. If not provided a [aws.sdk.kotlin.runtime.auth.credentials.DefaultChainCredentialsProvider] instance will be used." baseClass = AwsRuntimeTypes.Auth.ServicePresignConfig } val endpointResolverProperty = ClientConfigProperty { diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt index eb35364bf53..99536b1dabd 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt @@ -5,7 +5,6 @@ package aws.sdk.kotlin.codegen.protocols.middleware -import aws.sdk.kotlin.codegen.AwsKotlinDependency import aws.sdk.kotlin.codegen.AwsRuntimeTypes import software.amazon.smithy.aws.traits.auth.SigV4Trait import software.amazon.smithy.kotlin.codegen.core.KotlinWriter @@ -41,7 +40,7 @@ open class AwsSignatureVersion4(private val signingServiceName: String) : HttpFe override fun renderConfigure(writer: KotlinWriter) { writer.addImport(AwsRuntimeTypes.Auth.AwsSigV4SigningMiddleware) - writer.addImport("DefaultChainCredentialsProvider", AwsKotlinDependency.AWS_AUTH) + writer.addImport(AwsRuntimeTypes.Auth.DefaultChainCredentialsProvider) writer.write("this.credentialsProvider = config.credentialsProvider ?: DefaultChainCredentialsProvider()") writer.write("this.service = #S", signingServiceName) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/protocoltest/AwsHttpProtocolUnitTestRequestGenerator.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/protocoltest/AwsHttpProtocolUnitTestRequestGenerator.kt index 5507d6a642f..dc0b277e171 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/protocoltest/AwsHttpProtocolUnitTestRequestGenerator.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/protocoltest/AwsHttpProtocolUnitTestRequestGenerator.kt @@ -6,6 +6,7 @@ package aws.sdk.kotlin.codegen.protocols.protocoltest import aws.sdk.kotlin.codegen.AwsKotlinDependency +import aws.sdk.kotlin.codegen.AwsRuntimeTypes import aws.sdk.kotlin.codegen.protocols.middleware.AwsSignatureVersion4 import software.amazon.smithy.kotlin.codegen.core.KotlinWriter import software.amazon.smithy.kotlin.codegen.model.buildSymbol @@ -58,16 +59,8 @@ internal fun HttpProtocolUnitTestGenerator.renderCo operation: OperationShape ) { if (AwsSignatureVersion4.hasSigV4AuthScheme(model, serviceShape, operation)) { - val staticProviderSymbol = buildSymbol { - name = "StaticCredentialsProvider" - namespace(AwsKotlinDependency.AWS_AUTH) - } - val credentialsSymbol = buildSymbol { - name = "Credentials" - namespace(AwsKotlinDependency.AWS_AUTH) - } - writer.addImport(staticProviderSymbol) - writer.addImport(credentialsSymbol) + writer.addImport(AwsRuntimeTypes.Auth.StaticCredentialsProvider) + writer.addImport(AwsRuntimeTypes.Auth.Credentials) writer.write("val credentials = Credentials(#S, #S)", "AKID", "SECRET") writer.write("credentialsProvider = StaticCredentialsProvider(credentials)") } diff --git a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt index 78aebfe4bbc..ebd9e9fc222 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/PresignerGeneratorTest.kt @@ -246,7 +246,7 @@ class PresignerGeneratorTest { interface DslBuilder { /** - * The AWS credentials provider to use for authenticating requests. If not provided a [aws.sdk.kotlin.runtime.auth.DefaultChainCredentialsProvider] instance will be used. + * The AWS credentials provider to use for authenticating requests. If not provided a [aws.sdk.kotlin.runtime.auth.credentials.DefaultChainCredentialsProvider] instance will be used. */ var credentialsProvider: CredentialsProvider From b8a6bc72932f32425b4abef07ef160ef265eb70d Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Fri, 17 Sep 2021 13:34:43 -0400 Subject: [PATCH 5/9] fix s3 signing config --- .../aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt index bd96b749937..6d7c63decdc 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt @@ -45,7 +45,7 @@ private class S3SigningMiddleware(signingServiceName: String) : AwsSignatureVers super.renderConfigure(writer) val sbht = AwsRuntimeTypes.Auth.AwsSignedBodyHeaderType writer.addImport(sbht) - writer.write("signedBodyHeaderType = #T.X_AMZ_CONTENT_SHA256", sbht) + writer.write("signedBodyHeader = #T.X_AMZ_CONTENT_SHA256", sbht) // https://github.com/awslabs/aws-sdk-kotlin/issues/200 writer.write("useDoubleUriEncode = false") From d533c6daeb72446bd4e62c4ce05216fb36b8d196 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Mon, 20 Sep 2021 09:11:41 -0400 Subject: [PATCH 6/9] cleanup kdoc --- .../kotlin/runtime/auth/signing/AwsSigning.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt index 8cb0408730b..4ef5f2eec3d 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigning.kt @@ -13,6 +13,17 @@ import aws.smithy.kotlin.runtime.http.request.toBuilder /** * Container for signed output and signature + * + * @property output The signed output type (e.g. HttpRequest) + * @property signature The resulting signature. Depending on the requested signature type and algorithm, + * this value will be in one of the following formats: + * + * 1. [AwsSignatureType.HTTP_REQUEST_VIA_HEADERS] - hex encoding of the binary signature value + * 2. [AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS] - hex encoding of the binary signature value + * 3. [AwsSignatureType.HTTP_REQUEST_CHUNK] (SIGV4) - hex encoding of the binary signature value + * 4. [AwsSignatureType.HTTP_REQUEST_CHUNK] (SIGV4_ASYMMETRIC) - '*'-padded hex encoding of the binary signature value + * 5. [AwsSignatureType.HTTP_REQUEST_EVENT] - binary signature value (NYI) + * */ public data class SigningResult(val output: T, val signature: ByteArray) { override fun equals(other: Any?): Boolean { @@ -36,7 +47,10 @@ public data class SigningResult(val output: T, val signature: ByteArray) { /** * Sign [HttpRequest] using the given signing [config] - * @return signing result + * + * @param request the HTTP request to sign + * @param config the signing configuration to use + * @return the signing result */ public suspend fun sign(request: HttpRequest, config: AwsSigningConfig): SigningResult { val crtRequest = request.toSignableCrtRequest() From d8f0fe6487a60e750f153bcf5293f78560419db9 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Mon, 27 Sep 2021 11:43:04 -0400 Subject: [PATCH 7/9] revert back to using a dedicated type for middleware config --- .../auth/signing/AwsSigV4SigningMiddleware.kt | 81 ++++++++++++++----- .../signing/AwsSigv4SigningMiddlewareTest.kt | 2 +- .../middleware/AwsSignatureVersion4.kt | 2 +- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt index e19df655694..169b1b825bf 100644 --- a/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt +++ b/aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/signing/AwsSigV4SigningMiddleware.kt @@ -8,6 +8,7 @@ package aws.sdk.kotlin.runtime.auth.signing import aws.sdk.kotlin.crt.auth.signing.AwsSignedBodyValue import aws.sdk.kotlin.crt.auth.signing.AwsSigner import aws.sdk.kotlin.runtime.InternalSdkApi +import aws.sdk.kotlin.runtime.auth.credentials.CredentialsProvider import aws.sdk.kotlin.runtime.crt.toSignableCrtRequest import aws.sdk.kotlin.runtime.crt.update import aws.sdk.kotlin.runtime.execution.AuthAttributes @@ -22,24 +23,66 @@ import aws.smithy.kotlin.runtime.util.get * HTTP request pipeline middleware that signs outgoing requests */ @InternalSdkApi -public class AwsSigV4SigningMiddleware internal constructor(private val baseConfig: AwsSigningConfig) : Feature { +public class AwsSigV4SigningMiddleware internal constructor(private val config: Config) : Feature { + + public class Config { + /** + * The credentials provider used to sign requests with + */ + public var credentialsProvider: CredentialsProvider? = null + + /** + * The credential scope service name to sign requests for + * NOTE: The operation context is favored when [AuthAttributes.SigningService] is set + */ + public var signingService: String? = null + + /** + * Sets what signature should be computed + */ + public var signatureType: AwsSignatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS + + /** + * The algorithm to sign with + */ + public var algorithm: AwsSigningAlgorithm = AwsSigningAlgorithm.SIGV4 + + /** + * The uri is assumed to be encoded once in preparation for transmission. Certain services + * do not decode before checking signature, requiring double-encoding the uri in the canonical + * request in order to pass a signature check. + */ + public var useDoubleUriEncode: Boolean = true + + /** + * Controls whether or not the uri paths should be normalized when building the canonical request + */ + public var normalizeUriPath: Boolean = true + + /** + * Flag indicating if the "X-Amz-Security-Token" query param should be omitted. + * Normally, this parameter is added during signing if the credentials have a session token. + * The only known case where this should be true is when signing a websocket handshake to IoT Core. + */ + public var omitSessionToken: Boolean = false + + /** + * Controls what body "hash" header, if any, should be added to the canonical request and the signed request. + * Most services do not require this additional header. + */ + public var signedBodyHeaderType: AwsSignedBodyHeaderType = AwsSignedBodyHeaderType.NONE + } - public companion object Feature : HttpClientFeatureFactory { + public companion object Feature : HttpClientFeatureFactory { private val logger = Logger.getLogger() override val key: FeatureKey = FeatureKey("AwsSigv4SigningMiddleware") - override fun create(block: AwsSigningConfig.Builder.() -> Unit): AwsSigV4SigningMiddleware { - val builder = AwsSigningConfig.Builder().apply(block) - - // region is required when using a standalone signing config but the middleware takes the signing region - // (and other settings) from the operation execution attributes and combines them with the middleware - // defaults - if (builder.region == null) { builder.region = "" } - val config = builder.build() + override fun create(block: Config.() -> Unit): AwsSigV4SigningMiddleware { + val config = Config().apply(block) requireNotNull(config.credentialsProvider) { "AwsSigv4SigningMiddleware requires a credentialsProvider" } - requireNotNull(config.service) { "AwsSigv4SigningMiddleware requires a signing service" } + requireNotNull(config.signingService) { "AwsSigv4SigningMiddleware requires a signing service" } return AwsSigV4SigningMiddleware(config) } @@ -48,7 +91,7 @@ public class AwsSigV4SigningMiddleware internal constructor(private val baseConf override fun install(operation: SdkHttpOperation) { operation.execution.finalize.intercept { req, next -> - val credentialsProvider = checkNotNull(baseConfig.credentialsProvider) + val credentialsProvider = checkNotNull(config.credentialsProvider) val resolvedCredentials = credentialsProvider.getCredentials() val logger: Logger by lazy { logger.withContext(req.context) } @@ -80,17 +123,17 @@ public class AwsSigV4SigningMiddleware internal constructor(private val baseConf // operation signing config is baseConfig + operation specific config/overrides val opSigningConfig = AwsSigningConfig { region = req.context[AuthAttributes.SigningRegion] - service = req.context.getOrNull(AuthAttributes.SigningService) ?: checkNotNull(baseConfig.service) + service = req.context.getOrNull(AuthAttributes.SigningService) ?: checkNotNull(config.signingService) credentials = resolvedCredentials - algorithm = baseConfig.algorithm + algorithm = config.algorithm date = req.context.getOrNull(AuthAttributes.SigningDate) - signatureType = baseConfig.signatureType - omitSessionToken = baseConfig.omitSessionToken - normalizeUriPath = baseConfig.normalizeUriPath - useDoubleUriEncode = baseConfig.useDoubleUriEncode + signatureType = config.signatureType + omitSessionToken = config.omitSessionToken + normalizeUriPath = config.normalizeUriPath + useDoubleUriEncode = config.useDoubleUriEncode - signedBodyHeader = baseConfig.signedBodyHeaderType + signedBodyHeader = config.signedBodyHeaderType signedBodyValue = when { isUnsignedRequest -> AwsSignedBodyValue.UNSIGNED_PAYLOAD req.subject.body is HttpBody.Empty -> AwsSignedBodyValue.EMPTY_SHA256 diff --git a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt index d6c62c90790..4612c55ee5f 100644 --- a/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt +++ b/aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/signing/AwsSigv4SigningMiddlewareTest.kt @@ -69,7 +69,7 @@ class AwsSigv4SigningMiddlewareTest { operation.install(AwsSigV4SigningMiddleware) { credentialsProvider = TestCredentialsProvider - service = "demo" + signingService = "demo" } operation.roundTrip(client, Unit) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt index 99536b1dabd..ebe9ac2afa2 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/protocols/middleware/AwsSignatureVersion4.kt @@ -43,7 +43,7 @@ open class AwsSignatureVersion4(private val signingServiceName: String) : HttpFe writer.addImport(AwsRuntimeTypes.Auth.DefaultChainCredentialsProvider) writer.write("this.credentialsProvider = config.credentialsProvider ?: DefaultChainCredentialsProvider()") - writer.write("this.service = #S", signingServiceName) + writer.write("this.signingService = #S", signingServiceName) } companion object { From e53826b37019e7048a81d46484007558164264b8 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Mon, 27 Sep 2021 12:03:11 -0400 Subject: [PATCH 8/9] fix s3 signing config --- .../aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt index 6d7c63decdc..bd96b749937 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/S3SigningConfig.kt @@ -45,7 +45,7 @@ private class S3SigningMiddleware(signingServiceName: String) : AwsSignatureVers super.renderConfigure(writer) val sbht = AwsRuntimeTypes.Auth.AwsSignedBodyHeaderType writer.addImport(sbht) - writer.write("signedBodyHeader = #T.X_AMZ_CONTENT_SHA256", sbht) + writer.write("signedBodyHeaderType = #T.X_AMZ_CONTENT_SHA256", sbht) // https://github.com/awslabs/aws-sdk-kotlin/issues/200 writer.write("useDoubleUriEncode = false") From 9862c65f22ecc0e6324b9bd543ee4b4d14bd6944 Mon Sep 17 00:00:00 2001 From: Aaron J Todd Date: Mon, 27 Sep 2021 12:55:16 -0400 Subject: [PATCH 9/9] force rebuild