Skip to content

Commit 6291c96

Browse files
committed
feat: implement multi-auth scheme preferences per SEP
1 parent 92c4d9f commit 6291c96

File tree

12 files changed

+924
-36
lines changed

12 files changed

+924
-36
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"core": {
3+
"changeLogMessages": [
4+
"Implement multi-auth SEP with authentication scheme preference and SigV4a region set configuration",
5+
"Add AuthScheme, AuthSchemePreference, and related configuration classes",
6+
"Add DefaultAuthSchemeResolver and configuration resolution logic",
7+
"Update ClientConfig to support new authentication scheme properties",
8+
"Add environment and configuration file support for auth scheme settings"
9+
],
10+
"type": "minor",
11+
"updateMinimum": true
12+
}
13+
}

sdk/src/Core/AWSConfigs.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,64 @@ public static bool DisableLegacyPersistenceStore
402402

403403
#endregion
404404

405+
#region Authentication Scheme Preference
406+
407+
/// <summary>
408+
/// Key for the AuthSchemePreference property.
409+
/// <seealso cref="Amazon.AWSConfigs.AuthSchemePreference"/>
410+
/// </summary>
411+
public const string AuthSchemePreferenceKey = "AWSAuthSchemePreference";
412+
413+
/// <summary>
414+
/// Gets or sets the global authentication scheme preference for all AWS service clients.
415+
/// <para>
416+
/// This property allows you to specify a preference list of authentication schemes
417+
/// that will be used to reprioritize the supported authentication schemes globally.
418+
/// Individual client configurations can override this global setting.
419+
/// </para>
420+
/// <para>
421+
/// This setting can be configured through environment variables or configuration files:
422+
/// - Environment variable: AWS_AUTH_SCHEME_PREFERENCE
423+
/// - Configuration file: auth_scheme_preference
424+
/// </para>
425+
/// </summary>
426+
public static string AuthSchemePreference
427+
{
428+
get { return _rootConfig.AuthSchemePreference; }
429+
set { _rootConfig.AuthSchemePreference = value; }
430+
}
431+
432+
#endregion
433+
434+
#region SigV4a Region Set Configuration
435+
436+
/// <summary>
437+
/// Key for the SigV4aSigningRegionSet property.
438+
/// <seealso cref="Amazon.AWSConfigs.SigV4aSigningRegionSet"/>
439+
/// </summary>
440+
public const string SigV4aSigningRegionSetKey = "AWSSigV4aRegionSet";
441+
442+
/// <summary>
443+
/// Gets or sets the global SigV4a signing region set configuration for all AWS service clients.
444+
/// <para>
445+
/// This property allows you to specify the region set that will be used for SigV4a signing globally.
446+
/// The region set determines which regions the signed request is valid for.
447+
/// Individual client configurations can override this global setting.
448+
/// </para>
449+
/// <para>
450+
/// This setting can be configured through environment variables or configuration files:
451+
/// - Environment variable: AWS_SIGV4A_SIGNING_REGION_SET
452+
/// - Configuration file: sigv4a_signing_region_set
453+
/// </para>
454+
/// </summary>
455+
public static string SigV4aSigningRegionSet
456+
{
457+
get { return _rootConfig.SigV4aSigningRegionSet; }
458+
set { _rootConfig.SigV4aSigningRegionSet = value; }
459+
}
460+
461+
#endregion
462+
405463
#region AWS Config Sections
406464

407465
/// <summary>

sdk/src/Core/Amazon.Runtime/ClientConfig.cs

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
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-
*/
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+
*/
1515
using System;
1616
using System.Collections.Generic;
1717
using System.Net;
@@ -68,6 +68,7 @@ public abstract partial class ClientConfig : IClientConfig
6868
private string authServiceName = null;
6969
private string clientAppId = null;
7070
private SigningAlgorithm signatureMethod = SigningAlgorithm.HmacSHA256;
71+
private bool isSignatureMethodExplicitlySet = false;
7172
private bool logResponse = false;
7273
private int bufferSize = AWSSDKUtils.DefaultBufferSize;
7374
private long progressUpdateInterval = AWSSDKUtils.DefaultProgressUpdateInterval;
@@ -221,7 +222,20 @@ public abstract string ServiceVersion
221222
public SigningAlgorithm SignatureMethod
222223
{
223224
get { return this.signatureMethod; }
224-
set { this.signatureMethod = value; }
225+
set {
226+
this.signatureMethod = value;
227+
this.isSignatureMethodExplicitlySet = true;
228+
}
229+
}
230+
231+
/// <summary>
232+
/// Gets a value indicating whether the SignatureMethod property was explicitly set by the user.
233+
/// This is used for backwards compatibility to determine when legacy SignatureMethod configuration
234+
/// should take precedence over auth scheme preferences.
235+
/// </summary>
236+
public bool IsSignatureMethodExplicitlySet
237+
{
238+
get { return this.isSignatureMethodExplicitlySet; }
225239
}
226240

227241
/// <summary>
@@ -317,18 +331,18 @@ public abstract string RegionEndpointServiceName
317331
/// </summary>
318332
public string ServiceURL
319333
{
320-
get
334+
get
321335
{
322336
if (!didProcessServiceURL && this.serviceURL == null && IgnoreConfiguredEndpointUrls == false && ServiceId != null)
323337
{
324-
338+
325339
string serviceSpecificTransformedEnvironmentVariable = TransformServiceId.TransformServiceIdToEnvVariable(ServiceId);
326340
string transformedConfigServiceId = TransformServiceId.TransformServiceIdToConfigVariable(ServiceId);
327341

328342
if (Environment.GetEnvironmentVariable(serviceSpecificTransformedEnvironmentVariable) != null)
329343
{
330344
Logger.GetLogger(GetType()).InfoFormat($"ServiceURL configured from service specific environment variable: {serviceSpecificTransformedEnvironmentVariable}.");
331-
this.ServiceURL = Environment.GetEnvironmentVariable(serviceSpecificTransformedEnvironmentVariable);
345+
this.ServiceURL = Environment.GetEnvironmentVariable(serviceSpecificTransformedEnvironmentVariable);
332346
}
333347
else if (Environment.GetEnvironmentVariable(EnvironmentVariables.GLOBAL_ENDPOINT_ENVIRONMENT_VARIABLE) != null)
334348
{
@@ -381,7 +395,7 @@ public string ServiceURL
381395
$"ServiceUrl was set last, ServiceUrl: {value} will be used to make the request and RegionEndpoint: {this.regionEndpoint} has been set to null.");
382396
this.regionEndpoint = null;
383397
this.probeForRegionEndpoint = false;
384-
398+
385399
if(!string.IsNullOrEmpty(value))
386400
{
387401
// If the URL passed in only has a host name make sure there is an ending "/" to avoid signature mismatch issues.
@@ -444,7 +458,7 @@ public string AuthenticationServiceName
444458
get { return this.authServiceName; }
445459
set { this.authServiceName = value; }
446460
}
447-
461+
448462
/// <summary>
449463
/// The serviceId for the service, which is specified in the metadata in the ServiceModel.
450464
/// The transformed value of the service ID (replace any spaces in the service ID
@@ -540,7 +554,7 @@ public long ProgressUpdateInterval
540554
get { return progressUpdateInterval; }
541555
set { progressUpdateInterval = value; }
542556
}
543-
557+
544558

545559
/// <summary>
546560
/// Flag on whether to resign requests on retry or not.
@@ -638,7 +652,7 @@ protected IDefaultConfiguration DefaultConfiguration
638652
/// </summary>
639653
public ICredentials ProxyCredentials
640654
{
641-
get
655+
get
642656
{
643657
if(this.proxyCredentials == null &&
644658
(!string.IsNullOrEmpty(AWSConfigs.ProxyConfig.Username) ||
@@ -794,7 +808,7 @@ internal CancellationToken BuildDefaultCancellationToken()
794808
/// </remarks>
795809
public bool UseDualstackEndpoint
796810
{
797-
get
811+
get
798812
{
799813
if (!this.useDualstackEndpoint.HasValue)
800814
{
@@ -873,10 +887,10 @@ public long RequestMinCompressionSizeBytes
873887

874888
return this.requestMinCompressionSizeBytes.Value;
875889
}
876-
set
890+
set
877891
{
878892
ValidateMinCompression(value);
879-
requestMinCompressionSizeBytes = value;
893+
requestMinCompressionSizeBytes = value;
880894
}
881895
}
882896

@@ -902,7 +916,7 @@ public string ClientAppId
902916

903917
return this.clientAppId;
904918
}
905-
set
919+
set
906920
{
907921
ValidateClientAppId(value);
908922
this.clientAppId = value;
@@ -1034,7 +1048,7 @@ public RequestRetryMode RetryMode
10341048
}
10351049
set { this.retryMode = value; }
10361050
}
1037-
1051+
10381052
/// <summary>
10391053
/// Under Adaptive retry mode, this flag determines if the client should wait for
10401054
/// a send token to become available or don't block and fail the request immediately
@@ -1185,6 +1199,28 @@ public TelemetryProvider TelemetryProvider
11851199
set { this.telemetryProvider = value; }
11861200
}
11871201

1202+
/// <summary>
1203+
/// Gets or sets the authentication scheme preference for this client configuration.
1204+
/// <para>
1205+
/// This property allows you to specify a comma-separated preference list of authentication schemes
1206+
/// (e.g., "sigv4a,sigv4") that will be used to reprioritize the supported authentication schemes for this client.
1207+
/// If not set, the client will use environment variables, configuration files,
1208+
/// or fall back to the default model-based authentication scheme resolution.
1209+
/// </para>
1210+
/// </summary>
1211+
public string AuthSchemePreference { get; set; }
1212+
1213+
/// <summary>
1214+
/// Gets or sets the SigV4a signing region set for this client.
1215+
/// <para>
1216+
/// This property allows you to specify a comma-separated list of regions (e.g., "us-east-1,us-west-2")
1217+
/// that will be used for SigV4a signing. The region set determines which regions the signed request is valid for.
1218+
/// If not set, the client will use environment variables, configuration files,
1219+
/// endpoints metadata, or fall back to the client's configured region.
1220+
/// </para>
1221+
/// </summary>
1222+
public string SigV4aSigningRegionSet { get; set; }
1223+
11881224
/// <summary>
11891225
/// Determines the behavior for calculating checksums for request payloads.
11901226
/// By default it is set to <see cref="RequestChecksumCalculation.WHEN_SUPPORTED"/>.

sdk/src/Core/Amazon.Runtime/Credentials/Internal/AuthSchemeOption.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,31 @@ public class AuthSchemeOption : IAuthSchemeOption
2323
/// <inheritdoc/>
2424
public string SchemeId { get; set; }
2525

26+
/// <summary>
27+
/// Gets the short name of the authentication scheme (e.g., "sigv4" from "aws.auth#sigv4").
28+
/// This is used for configuration purposes.
29+
/// </summary>
30+
public string Name => GetNameFromSchemeId(SchemeId);
31+
2632
internal const string SigV4 = "aws.auth#sigv4";
2733
internal const string SigV4A = "aws.auth#sigv4a";
2834
internal const string Bearer = "smithy.api#httpBearerAuth";
2935
internal const string NoAuth = "smithy.api#noAuth";
3036

37+
/// <summary>
38+
/// Extracts the short name from a fully qualified scheme ID.
39+
/// </summary>
40+
/// <param name="schemeId">The fully qualified scheme ID (e.g., "aws.auth#sigv4").</param>
41+
/// <returns>The short name (e.g., "sigv4") or the original schemeId if no '#' is present.</returns>
42+
public static string GetNameFromSchemeId(string schemeId)
43+
{
44+
if (string.IsNullOrEmpty(schemeId))
45+
return schemeId;
46+
47+
var parts = schemeId.Split('#');
48+
return parts.Length > 1 ? parts[1] : schemeId;
49+
}
50+
3151
/// <summary>
3252
/// Default auth scheme options for services / operations that only support SigV4.
3353
/// </summary>

sdk/src/Core/Amazon.Runtime/IClientConfig.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@ public partial interface IClientConfig
148148
/// </summary>
149149
SigningAlgorithm SignatureMethod { get; }
150150

151+
/// <summary>
152+
/// Gets a value indicating whether the SignatureMethod property was explicitly set by the user.
153+
/// This is used for backwards compatibility to determine when legacy SignatureMethod configuration
154+
/// should take precedence over auth scheme preferences.
155+
/// </summary>
156+
bool IsSignatureMethodExplicitlySet { get; }
157+
158+
151159
/// <summary>
152160
/// Gets the AuthenticationRegion property.
153161
/// Used in AWS4 request signing, this is an optional property;
@@ -397,6 +405,30 @@ public partial interface IClientConfig
397405
/// </summary>
398406
ResponseChecksumValidation ResponseChecksumValidation { get; }
399407

408+
/// <summary>
409+
/// Gets or sets the authentication scheme preference for this client configuration.
410+
/// <para>
411+
/// This property allows you to specify a comma-separated preference list of authentication schemes
412+
/// (e.g., "sigv4a,sigv4") that will be used to reprioritize the supported authentication schemes for this client.
413+
/// If not set, the client will use environment variables, configuration files,
414+
/// or fall back to the default model-based authentication scheme resolution.
415+
/// </para>
416+
/// </summary>
417+
string AuthSchemePreference { get; }
418+
419+
/// <summary>
420+
/// Gets or sets the SigV4a signing region set for this client.
421+
/// <para>
422+
/// This property allows you to specify a comma-separated list of regions (e.g., "us-east-1,us-west-2")
423+
/// that will be used for SigV4a signing. The region set determines which regions the signed request is valid for.
424+
/// If not set, the client will use environment variables, configuration files,
425+
/// endpoints metadata, or fall back to the client's configured region.
426+
/// </para>
427+
/// </summary>
428+
string SigV4aSigningRegionSet { get; }
429+
430+
431+
400432
/// <summary>
401433
/// Controls whether the resolved endpoint will include the account id. This allows for direct routing of traffic
402434
/// to the cell responsible for a given account, which avoids the additional latency of extra backend hops and reduces

0 commit comments

Comments
 (0)