Skip to content

Commit 452976d

Browse files
authored
feat: add authSchemePreference configuration (#1582)
1 parent 0dc1f01 commit 452976d

File tree

8 files changed

+163
-2
lines changed

8 files changed

+163
-2
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "8d7689ef-8acf-4fb3-84b9-712b704725e8",
3+
"type": "feature",
4+
"description": "Add `authSchemePreference` configuration"
5+
}

aws-runtime/aws-config/api/aws-config.api

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ public final class aws/sdk/kotlin/runtime/config/AwsSdkSetting {
252252
public final fun getAwsAccountId ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
253253
public final fun getAwsAccountIdEndpointMode ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
254254
public final fun getAwsAppId ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
255+
public final fun getAwsAuthSchemePreference ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
255256
public final fun getAwsConfigFile ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
256257
public final fun getAwsContainerAuthorizationToken ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
257258
public final fun getAwsContainerAuthorizationTokenFile ()Laws/smithy/kotlin/runtime/config/EnvironmentSetting;
@@ -287,6 +288,11 @@ public final class aws/sdk/kotlin/runtime/config/AwsSdkSettingKt {
287288
public static final fun resolveEndpointUrl (Laws/sdk/kotlin/runtime/config/AwsSdkSetting;Laws/smithy/kotlin/runtime/util/PlatformProvider;Ljava/lang/String;Ljava/lang/String;)Laws/smithy/kotlin/runtime/net/url/Url;
288289
}
289290

291+
public final class aws/sdk/kotlin/runtime/config/auth/ResolveAuthSchemePreferenceKt {
292+
public static final fun resolveAuthSchemePreference (Laws/smithy/kotlin/runtime/util/PlatformProvider;Laws/smithy/kotlin/runtime/util/LazyAsyncValue;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
293+
public static synthetic fun resolveAuthSchemePreference$default (Laws/smithy/kotlin/runtime/util/PlatformProvider;Laws/smithy/kotlin/runtime/util/LazyAsyncValue;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
294+
}
295+
290296
public final class aws/sdk/kotlin/runtime/config/checksums/ResolveFlexibleChecksumsConfigKt {
291297
public static final fun resolveRequestChecksumCalculation (Laws/smithy/kotlin/runtime/util/PlatformProvider;Laws/smithy/kotlin/runtime/util/LazyAsyncValue;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
292298
public static synthetic fun resolveRequestChecksumCalculation$default (Laws/smithy/kotlin/runtime/util/PlatformProvider;Laws/smithy/kotlin/runtime/util/LazyAsyncValue;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
@@ -499,6 +505,7 @@ public final class aws/sdk/kotlin/runtime/config/profile/AwsConfigurationSource
499505

500506
public final class aws/sdk/kotlin/runtime/config/profile/AwsProfileKt {
501507
public static final fun getAccountIdEndpointMode (Laws/sdk/kotlin/runtime/config/profile/ConfigSection;)Laws/sdk/kotlin/runtime/config/endpoints/AccountIdEndpointMode;
508+
public static final fun getAuthSchemePreference (Laws/sdk/kotlin/runtime/config/profile/ConfigSection;)Ljava/lang/String;
502509
public static final fun getAwsAccessKeyId (Laws/sdk/kotlin/runtime/config/profile/ConfigSection;)Ljava/lang/String;
503510
public static final fun getAwsSecretAccessKey (Laws/sdk/kotlin/runtime/config/profile/ConfigSection;)Ljava/lang/String;
504511
public static final fun getAwsSessionToken (Laws/sdk/kotlin/runtime/config/profile/ConfigSection;)Ljava/lang/String;

aws-runtime/aws-config/common/src/aws/sdk/kotlin/runtime/config/AbstractAwsSdkClientFactory.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package aws.sdk.kotlin.runtime.config
77

88
import aws.sdk.kotlin.runtime.client.AwsSdkClientConfig
9+
import aws.sdk.kotlin.runtime.config.auth.resolveAuthSchemePreference
910
import aws.sdk.kotlin.runtime.config.checksums.resolveRequestChecksumCalculation
1011
import aws.sdk.kotlin.runtime.config.checksums.resolveResponseChecksumValidation
1112
import aws.sdk.kotlin.runtime.config.compression.resolveDisableRequestCompression
@@ -26,6 +27,7 @@ import aws.smithy.kotlin.runtime.client.config.ClientSettings
2627
import aws.smithy.kotlin.runtime.client.config.CompressionClientConfig
2728
import aws.smithy.kotlin.runtime.client.config.HttpChecksumConfig
2829
import aws.smithy.kotlin.runtime.config.resolve
30+
import aws.smithy.kotlin.runtime.http.auth.HttpAuthConfig
2931
import aws.smithy.kotlin.runtime.telemetry.TelemetryConfig
3032
import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider
3133
import aws.smithy.kotlin.runtime.telemetry.trace.withSpan
@@ -105,6 +107,10 @@ public abstract class AbstractAwsSdkClientFactory<
105107
config.responseChecksumValidation ?: resolveResponseChecksumValidation(platform, profile)
106108
}
107109

110+
if (config is HttpAuthConfig.Builder) {
111+
config.authSchemePreference = config.authSchemePreference ?: resolveAuthSchemePreference(platform, profile)
112+
}
113+
108114
finalizeConfig(builder)
109115
finalizeEnvironmentalConfig(builder, sharedConfig, profile)
110116
}

aws-runtime/aws-config/common/src/aws/sdk/kotlin/runtime/config/AwsSdkSetting.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ public object AwsSdkSetting {
230230
*/
231231
public val AwsResponseChecksumValidation: EnvironmentSetting<ResponseHttpChecksumConfig> =
232232
enumEnvSetting<ResponseHttpChecksumConfig>("aws.responseChecksumValidation", "AWS_RESPONSE_CHECKSUM_VALIDATION")
233+
234+
/**
235+
* Configures an ordered preference of auth schemes
236+
*/
237+
public val AwsAuthSchemePreference: EnvironmentSetting<String> = strEnvSetting("aws.authSchemePreference", "AWS_AUTH_SCHEME_PREFERENCE")
233238
}
234239

235240
/**
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package aws.sdk.kotlin.runtime.config.auth
2+
3+
import aws.sdk.kotlin.runtime.InternalSdkApi
4+
import aws.sdk.kotlin.runtime.config.AwsSdkSetting
5+
import aws.sdk.kotlin.runtime.config.profile.AwsProfile
6+
import aws.sdk.kotlin.runtime.config.profile.authSchemePreference
7+
import aws.smithy.kotlin.runtime.auth.AuthSchemeId
8+
import aws.smithy.kotlin.runtime.config.resolve
9+
import aws.smithy.kotlin.runtime.util.LazyAsyncValue
10+
import aws.smithy.kotlin.runtime.util.PlatformProvider
11+
12+
@InternalSdkApi
13+
public suspend fun resolveAuthSchemePreference(platform: PlatformProvider = PlatformProvider.System, profile: LazyAsyncValue<AwsProfile>): List<AuthSchemeId> {
14+
val content = AwsSdkSetting.AwsAuthSchemePreference.resolve(platform) ?: profile.get().authSchemePreference
15+
16+
return content
17+
?.split(",")
18+
?.map { it.trim() }
19+
?.filter { it.isNotEmpty() }
20+
?.map(::AuthSchemeId)
21+
?.toList()
22+
?: emptyList()
23+
}

aws-runtime/aws-config/common/src/aws/sdk/kotlin/runtime/config/profile/AwsProfile.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import aws.sdk.kotlin.runtime.config.endpoints.AccountIdEndpointMode
1111
import aws.smithy.kotlin.runtime.client.config.RequestHttpChecksumConfig
1212
import aws.smithy.kotlin.runtime.client.config.ResponseHttpChecksumConfig
1313
import aws.smithy.kotlin.runtime.client.config.RetryMode
14+
import aws.smithy.kotlin.runtime.http.auth.AuthScheme
1415
import aws.smithy.kotlin.runtime.net.url.Url
1516

1617
/**
@@ -169,6 +170,13 @@ public val AwsProfile.requestChecksumCalculation: RequestHttpChecksumConfig?
169170
public val AwsProfile.responseChecksumValidation: ResponseHttpChecksumConfig?
170171
get() = getEnumOrNull<ResponseHttpChecksumConfig>("response_checksum_validation")
171172

173+
/**
174+
* The ordered preference of [AuthScheme] that this client will use
175+
*/
176+
@InternalSdkApi
177+
public val AwsProfile.authSchemePreference: String?
178+
get() = getOrNull("auth_scheme_preference")
179+
172180
/**
173181
* Specifies a named EC2 instance profile to use which allows bypassing auto-discovery
174182
*/
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.sdk.kotlin.runtime.config.auth
6+
7+
import aws.sdk.kotlin.runtime.config.profile.AwsConfigurationSource
8+
import aws.sdk.kotlin.runtime.config.profile.FileType
9+
import aws.sdk.kotlin.runtime.config.profile.parse
10+
import aws.sdk.kotlin.runtime.config.profile.toSharedConfig
11+
import aws.smithy.kotlin.runtime.auth.AuthSchemeId
12+
import aws.smithy.kotlin.runtime.telemetry.logging.Logger
13+
import aws.smithy.kotlin.runtime.util.TestPlatformProvider
14+
import aws.smithy.kotlin.runtime.util.asyncLazy
15+
import kotlinx.coroutines.test.runTest
16+
import kotlin.test.Test
17+
import kotlin.test.assertEquals
18+
19+
class ResolveAuthSchemePreferenceTest {
20+
@Test
21+
fun testProfile() = runTest {
22+
assertEquals(
23+
AuthSchemeId("sigv4"),
24+
testResolveAuthSchemePreference(
25+
profileContent = """
26+
[default]
27+
auth_scheme_preference = sigv4
28+
""".trimIndent(),
29+
).single(),
30+
)
31+
}
32+
33+
@Test
34+
fun testEnvironment() = runTest {
35+
// Environment takes precedence over profile
36+
assertEquals(
37+
AuthSchemeId("sigv4a"),
38+
testResolveAuthSchemePreference(
39+
env = mapOf("AWS_AUTH_SCHEME_PREFERENCE" to "sigv4a"),
40+
profileContent = """
41+
[default]
42+
auth_scheme_preference = sigv4
43+
""".trimIndent(),
44+
).single(),
45+
)
46+
}
47+
48+
@Test
49+
fun testSystemProperties() = runTest {
50+
// System properties take precedence over environment and profile
51+
assertEquals(
52+
AuthSchemeId("httpBearerAuth"),
53+
testResolveAuthSchemePreference(
54+
env = mapOf("AWS_AUTH_SCHEME_PREFERENCE" to "sigv4a"),
55+
sysProps = mapOf("aws.authSchemePreference" to "httpBearerAuth"),
56+
profileContent = """
57+
[default]
58+
auth_scheme_preference = sigv4
59+
""".trimIndent(),
60+
).single(),
61+
)
62+
}
63+
64+
@Test
65+
fun testResolveMultipleSchemes() = runTest {
66+
assertEquals(
67+
listOf(AuthSchemeId("httpBearerAuth"), AuthSchemeId("sigv4a"), AuthSchemeId("sigv4")),
68+
testResolveAuthSchemePreference(
69+
env = mapOf("AWS_AUTH_SCHEME_PREFERENCE" to "httpBearerAuth, sigv4a, sigv4"),
70+
),
71+
)
72+
}
73+
74+
@Test
75+
fun testIgnoreWhitespace() = runTest {
76+
assertEquals(
77+
listOf(AuthSchemeId("httpBearerAuth"), AuthSchemeId("sigv4a")),
78+
testResolveAuthSchemePreference(
79+
env = mapOf("AWS_AUTH_SCHEME_PREFERENCE" to "httpBearerAuth , sigv4a "),
80+
),
81+
)
82+
}
83+
84+
@Test
85+
fun testDontFailOnInvalidSchemes() = runTest {
86+
assertEquals(
87+
listOf(AuthSchemeId("httpBearerAuth"), AuthSchemeId("whatIsThisScheme"), AuthSchemeId("sigv4")),
88+
testResolveAuthSchemePreference(
89+
env = mapOf("AWS_AUTH_SCHEME_PREFERENCE" to "httpBearerAuth, whatIsThisScheme, sigv4"),
90+
),
91+
)
92+
}
93+
94+
private suspend fun testResolveAuthSchemePreference(
95+
env: Map<String, String> = mapOf(),
96+
sysProps: Map<String, String> = mapOf(),
97+
profileContent: String = "",
98+
): List<AuthSchemeId> {
99+
val platform = TestPlatformProvider(env = env, props = sysProps)
100+
val source = AwsConfigurationSource("default", "", "")
101+
val profile = asyncLazy {
102+
parse(Logger.None, FileType.CONFIGURATION, profileContent).toSharedConfig(source).activeProfile
103+
}
104+
105+
return resolveAuthSchemePreference(platform, profile)
106+
}
107+
}

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ atomicfu-version = "0.25.0"
1212
binary-compatibility-validator-version = "0.16.3"
1313

1414
# smithy-kotlin codegen and runtime are versioned separately
15-
smithy-kotlin-runtime-version = "1.4.15"
16-
smithy-kotlin-codegen-version = "0.34.15"
15+
smithy-kotlin-runtime-version = "1.4.16"
16+
smithy-kotlin-codegen-version = "0.34.16"
1717

1818
# codegen
1919
smithy-version = "1.53.0"

0 commit comments

Comments
 (0)