diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index 80df1a0465e..8e681091fe2 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Feature - Add :expiration accessor to `CredentialProvider` and do not refresh credentials when checking expiration. + 3.175.0 (2023-06-15) ------------------ diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb b/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb index 1c8d30aea67..89b676daddb 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb @@ -6,6 +6,9 @@ module CredentialProvider # @return [Credentials] attr_reader :credentials + # @param [Time] + attr_reader :expiration + # @return [Boolean] def set? !!credentials && credentials.set? diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/refreshing_credentials.rb b/gems/aws-sdk-core/lib/aws-sdk-core/refreshing_credentials.rb index 4b19f65bee7..946a8d5ec7e 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/refreshing_credentials.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/refreshing_credentials.rb @@ -36,12 +36,6 @@ def credentials @credentials end - # @return [Time,nil] - def expiration - refresh_if_near_expiration! - @expiration - end - # Refresh credentials. # @return [void] def refresh! diff --git a/gems/aws-sdk-s3/CHANGELOG.md b/gems/aws-sdk-s3/CHANGELOG.md index 37b0e9f5bbb..996902180a2 100644 --- a/gems/aws-sdk-s3/CHANGELOG.md +++ b/gems/aws-sdk-s3/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Feature - Select minimum expiration time for presigned urls between the expiration time option and the credential expiration time. + 1.126.0 (2023-06-16) ------------------ diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb index d970c1e002a..5705aec3b12 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb @@ -49,7 +49,8 @@ def initialize(options = {}) # before the presigned URL expires. Defaults to 15 minutes. As signature # version 4 has a maximum expiry time of one week for presigned URLs, # attempts to set this value to greater than one week (604800) will - # raise an exception. + # raise an exception. The min value of this option and the credentials + # expiration time is used in the presigned URL. # # @option params [Time] :time (Time.now) The starting time for when the # presigned url becomes active. @@ -96,7 +97,8 @@ def presigned_url(method, params = {}) # before the presigned URL expires. Defaults to 15 minutes. As signature # version 4 has a maximum expiry time of one week for presigned URLs, # attempts to set this value to greater than one week (604800) will - # raise an exception. + # raise an exception. The min value of this option and the credentials + # expiration time is used in the presigned URL. # # @option params [Time] :time (Time.now) The starting time for when the # presigned url becomes active. diff --git a/gems/aws-sigv4/CHANGELOG.md b/gems/aws-sigv4/CHANGELOG.md index 0e2cd314c0b..9bf1d87b686 100644 --- a/gems/aws-sigv4/CHANGELOG.md +++ b/gems/aws-sigv4/CHANGELOG.md @@ -1,6 +1,9 @@ Unreleased Changes ------------------ +* Feature - Select the minimum expiration time for presigned urls between + the expiration time option and the credential expiration time. + 1.5.2 (2022-09-30) ------------------ diff --git a/gems/aws-sigv4/lib/aws-sigv4/signer.rb b/gems/aws-sigv4/lib/aws-sigv4/signer.rb index 7411531a477..1af8fa20702 100644 --- a/gems/aws-sigv4/lib/aws-sigv4/signer.rb +++ b/gems/aws-sigv4/lib/aws-sigv4/signer.rb @@ -423,7 +423,7 @@ def presign_url(options) params['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256' params['X-Amz-Credential'] = credential(creds, date) params['X-Amz-Date'] = datetime - params['X-Amz-Expires'] = extract_expires_in(options) + params['X-Amz-Expires'] = presigned_url_expiration(options, creds).to_s params['X-Amz-Security-Token'] = creds.session_token if creds.session_token params['X-Amz-SignedHeaders'] = signed_headers(headers) @@ -526,7 +526,6 @@ def event_signature(secret_access_key, date, string_to_sign) hmac(k_credentials, string_to_sign) end - def path(url) path = url.path path = '/' if path == '' @@ -682,8 +681,8 @@ def downcase_headers(headers) def extract_expires_in(options) case options[:expires_in] - when nil then 900.to_s - when Integer then options[:expires_in].to_s + when nil then 900 + when Integer then options[:expires_in] else msg = "expected :expires_in to be a number of seconds" raise ArgumentError, msg @@ -698,7 +697,6 @@ def uri_escape_path(string) self.class.uri_escape_path(string) end - def fetch_credentials credentials = @credentials_provider.credentials if credentials_set?(credentials) @@ -720,21 +718,30 @@ def credentials_set?(credentials) !credentials.secret_access_key.empty? end + def presigned_url_expiration(options, creds) + expires_in = extract_expires_in(options) + return expires_in unless creds.respond_to?(:expiration) + + creds_expiration_seconds = (creds.expiration - Time.now).to_i + [expires_in, creds_expiration_seconds].min + end + ### CRT Code # the credentials used by CRT must be a # CRT StaticCredentialsProvider object def crt_fetch_credentials creds = fetch_credentials - Aws::Crt::Auth::StaticCredentialsProvider.new( + crt_creds = Aws::Crt::Auth::StaticCredentialsProvider.new( creds.access_key_id, creds.secret_access_key, creds.session_token ) + [crt_creds, creds] end def crt_sign_request(request) - creds = crt_fetch_credentials + creds, _ = crt_fetch_credentials http_method = extract_http_method(request) url = extract_url(request) headers = downcase_headers(request[:headers]) @@ -793,7 +800,7 @@ def crt_sign_request(request) end def crt_presign_url(options) - creds = crt_fetch_credentials + creds, ruby_creds = crt_fetch_credentials http_method = extract_http_method(options) url = extract_url(options) @@ -821,7 +828,7 @@ def crt_presign_url(options) use_double_uri_encode: @uri_escape_path, should_normalize_uri_path: @normalize_path, omit_session_token: @omit_session_token, - expiration_in_seconds: options.fetch(:expires_in, 900) + expiration_in_seconds: presigned_url_expiration(options, ruby_creds) ) http_request = Aws::Crt::Http::Message.new( http_method, url.to_s, headers