Skip to content

Commit b1ce5e3

Browse files
authored
Recalculate signing time for every retry attempt (#2643)
## Motivation and Context When SigV4 signing was ported over to the orchestrator, the request time got calculated once before the retry loop, which was incorrect. This PR moves that request time calculation into the request signer so that it happens on every attempt (unless there is a configured request time override). This PR also refactors auth to use the `ConfigBag` instead of a separate signing properties `PropertyBag`. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent 5a8fff7 commit b1ce5e3

File tree

16 files changed

+280
-499
lines changed

16 files changed

+280
-499
lines changed

aws/rust-runtime/aws-runtime/src/auth.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ pub mod sigv4 {
1111
SignableRequest, SignatureLocation, SigningParams, SigningSettings,
1212
UriPathNormalizationMode,
1313
};
14-
use aws_smithy_http::property_bag::PropertyBag;
14+
use aws_smithy_runtime_api::client::auth::{AuthSchemeId, HttpAuthScheme, HttpRequestSigner};
1515
use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver, IdentityResolvers};
16-
use aws_smithy_runtime_api::client::orchestrator::{
17-
BoxError, HttpAuthScheme, HttpRequest, HttpRequestSigner,
18-
};
16+
use aws_smithy_runtime_api::client::orchestrator::{BoxError, ConfigBagAccessors, HttpRequest};
17+
use aws_smithy_runtime_api::config_bag::ConfigBag;
1918
use aws_types::region::SigningRegion;
2019
use aws_types::SigningService;
2120
use std::time::{Duration, SystemTime};
@@ -24,7 +23,7 @@ pub mod sigv4 {
2423
`expires_in` duration because the credentials used to sign it will expire first.";
2524

2625
/// Auth scheme ID for SigV4.
27-
pub const SCHEME_ID: &str = "sigv4";
26+
pub const SCHEME_ID: AuthSchemeId = AuthSchemeId::new("sigv4");
2827

2928
/// SigV4 auth scheme.
3029
#[derive(Debug, Default)]
@@ -40,7 +39,7 @@ pub mod sigv4 {
4039
}
4140

4241
impl HttpAuthScheme for SigV4HttpAuthScheme {
43-
fn scheme_id(&self) -> &'static str {
42+
fn scheme_id(&self) -> AuthSchemeId {
4443
SCHEME_ID
4544
}
4645

@@ -88,8 +87,6 @@ pub mod sigv4 {
8887
pub signing_optional: bool,
8988
/// Optional expiration (for presigning)
9089
pub expires_in: Option<Duration>,
91-
/// Timestamp to sign with.
92-
pub request_timestamp: SystemTime,
9390
}
9491

9592
impl Default for SigningOptions {
@@ -103,7 +100,6 @@ pub mod sigv4 {
103100
signature_type: HttpSignatureType::HttpRequestHeaders,
104101
signing_optional: false,
105102
expires_in: None,
106-
request_timestamp: SystemTime::now(),
107103
}
108104
}
109105
}
@@ -168,11 +164,11 @@ pub mod sigv4 {
168164
settings: SigningSettings,
169165
credentials: &'a Credentials,
170166
operation_config: &'a SigV4OperationSigningConfig,
167+
request_timestamp: SystemTime,
171168
) -> SigningParams<'a> {
172169
if let Some(expires_in) = settings.expires_in {
173170
if let Some(creds_expires_time) = credentials.expiry() {
174-
let presigned_expires_time =
175-
operation_config.signing_options.request_timestamp + expires_in;
171+
let presigned_expires_time = request_timestamp + expires_in;
176172
if presigned_expires_time > creds_expires_time {
177173
tracing::warn!(EXPIRATION_WARNING);
178174
}
@@ -184,7 +180,7 @@ pub mod sigv4 {
184180
.secret_key(credentials.secret_access_key())
185181
.region(operation_config.region.as_ref())
186182
.service_name(operation_config.service.as_ref())
187-
.time(operation_config.signing_options.request_timestamp)
183+
.time(request_timestamp)
188184
.settings(settings);
189185
builder.set_security_token(credentials.session_token());
190186
builder.build().expect("all required fields set")
@@ -196,12 +192,12 @@ pub mod sigv4 {
196192
&self,
197193
request: &mut HttpRequest,
198194
identity: &Identity,
199-
// TODO(enableNewSmithyRuntime): should this be the config bag?
200-
signing_properties: &PropertyBag,
195+
config_bag: &ConfigBag,
201196
) -> Result<(), BoxError> {
202-
let operation_config = signing_properties
197+
let operation_config = config_bag
203198
.get::<SigV4OperationSigningConfig>()
204199
.ok_or("missing operation signing config for SigV4")?;
200+
let request_time = config_bag.request_time().unwrap_or_default().system_time();
205201

206202
let credentials = if let Some(creds) = identity.data::<Credentials>() {
207203
creds
@@ -213,7 +209,8 @@ pub mod sigv4 {
213209
};
214210

215211
let settings = Self::settings(operation_config);
216-
let signing_params = Self::signing_params(settings, credentials, operation_config);
212+
let signing_params =
213+
Self::signing_params(settings, credentials, operation_config, request_time);
217214

218215
let (signing_instructions, _signature) = {
219216
// A body that is already in memory can be signed directly. A body that is not in memory
@@ -283,17 +280,16 @@ pub mod sigv4 {
283280
signature_type: HttpSignatureType::HttpRequestHeaders,
284281
signing_optional: false,
285282
expires_in: None,
286-
request_timestamp: now,
287283
payload_override: None,
288284
},
289285
};
290-
SigV4HttpRequestSigner::signing_params(settings, &credentials, &operation_config);
286+
SigV4HttpRequestSigner::signing_params(settings, &credentials, &operation_config, now);
291287
assert!(!logs_contain(EXPIRATION_WARNING));
292288

293289
let mut settings = SigningSettings::default();
294290
settings.expires_in = Some(creds_expire_in + Duration::from_secs(10));
295291

296-
SigV4HttpRequestSigner::signing_params(settings, &credentials, &operation_config);
292+
SigV4HttpRequestSigner::signing_params(settings, &credentials, &operation_config, now);
297293
assert!(logs_contain(EXPIRATION_WARNING));
298294
}
299295
}

aws/rust-runtime/aws-runtime/src/identity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
/// Credentials-based identity support.
77
pub mod credentials {
88
use aws_credential_types::cache::SharedCredentialsCache;
9-
use aws_smithy_http::property_bag::PropertyBag;
109
use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver};
1110
use aws_smithy_runtime_api::client::orchestrator::{BoxError, Future};
11+
use aws_smithy_runtime_api::config_bag::ConfigBag;
1212

1313
/// Smithy identity resolver for AWS credentials.
1414
#[derive(Debug)]
@@ -24,7 +24,7 @@ pub mod credentials {
2424
}
2525

2626
impl IdentityResolver for CredentialsIdentityResolver {
27-
fn resolve_identity(&self, _identity_properties: &PropertyBag) -> Future<Identity> {
27+
fn resolve_identity(&self, _config_bag: &ConfigBag) -> Future<Identity> {
2828
let cache = self.credentials_cache.clone();
2929
Future::new(Box::pin(async move {
3030
let credentials = cache.as_ref().provide_cached_credentials().await?;

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@ private class AuthOperationRuntimePluginCustomization(private val codegenContext
102102
val runtimeApi = RuntimeType.smithyRuntimeApi(runtimeConfig)
103103
val awsRuntime = AwsRuntimeType.awsRuntime(runtimeConfig)
104104
arrayOf(
105-
"AuthOptionListResolver" to runtimeApi.resolve("client::auth::option_resolver::AuthOptionListResolver"),
106-
"HttpAuthOption" to runtimeApi.resolve("client::orchestrator::HttpAuthOption"),
105+
"StaticAuthOptionResolver" to runtimeApi.resolve("client::auth::option_resolver::StaticAuthOptionResolver"),
107106
"HttpSignatureType" to awsRuntime.resolve("auth::sigv4::HttpSignatureType"),
108-
"PropertyBag" to RuntimeType.smithyHttp(runtimeConfig).resolve("property_bag::PropertyBag"),
109107
"SIGV4_SCHEME_ID" to awsRuntime.resolve("auth::sigv4::SCHEME_ID"),
110108
"SigV4OperationSigningConfig" to awsRuntime.resolve("auth::sigv4::SigV4OperationSigningConfig"),
111109
"SigningOptions" to awsRuntime.resolve("auth::sigv4::SigningOptions"),
@@ -136,16 +134,15 @@ private class AuthOperationRuntimePluginCustomization(private val codegenContext
136134
signing_options.normalize_uri_path = $normalizeUrlPath;
137135
signing_options.signing_optional = $signingOptional;
138136
signing_options.payload_override = #{payload_override};
139-
signing_options.request_timestamp = cfg.request_time().unwrap_or_default().system_time();
140137
141-
let mut sigv4_properties = #{PropertyBag}::new();
142-
sigv4_properties.insert(#{SigV4OperationSigningConfig} {
138+
${section.configBagName}.put(#{SigV4OperationSigningConfig} {
143139
region: signing_region,
144140
service: signing_service,
145141
signing_options,
146142
});
147-
let auth_option_resolver = #{AuthOptionListResolver}::new(
148-
vec![#{HttpAuthOption}::new(#{SIGV4_SCHEME_ID}, std::sync::Arc::new(sigv4_properties))]
143+
// TODO(enableNewSmithyRuntime): Make auth options additive in the config bag so that multiple codegen decorators can register them
144+
let auth_option_resolver = #{StaticAuthOptionResolver}::new(
145+
vec![#{SIGV4_SCHEME_ID}]
149146
);
150147
${section.configBagName}.set_auth_option_resolver(auth_option_resolver);
151148
""",

0 commit comments

Comments
 (0)