class Aws::Plugins::Sign::SignatureV4

@api private

Public Class Methods

new(auth_scheme, config, sigv4_overrides = {}) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 95
def initialize(auth_scheme, config, sigv4_overrides = {})
  scheme_name = auth_scheme['name']

  unless %w[sigv4 sigv4a sigv4-s3express].include?(scheme_name)
    raise ArgumentError,
          "Expected sigv4, sigv4a, or sigv4-s3express auth scheme, got #{scheme_name}"
  end

  region = if scheme_name == 'sigv4a'
             auth_scheme['signingRegionSet'].join(',')
           else
             auth_scheme['signingRegion']
           end
  begin
    @signer = config.sigv4_signer || Aws::Sigv4::Signer.new(
      service: config.sigv4_name || auth_scheme['signingName'],
      region: sigv4_overrides[:region] || config.sigv4_region || region,
      credentials_provider: sigv4_overrides[:credentials] || config.credentials,
      signing_algorithm: scheme_name.to_sym,
      uri_escape_path: !!!auth_scheme['disableDoubleEncoding'],
      normalize_path: !!!auth_scheme['disableNormalizePath'],
      unsigned_headers: %w[content-length user-agent x-amzn-trace-id]
    )
  rescue Aws::Sigv4::Errors::MissingCredentialsError
    raise Aws::Errors::MissingCredentialsError
  end
end

Public Instance Methods

presign_url(*args) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 150
def presign_url(*args)
  @signer.presign_url(*args)
end
sign(context) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 123
def sign(context)
  req = context.http_request

  apply_authtype(context, req)
  reset_signature(req)
  apply_clock_skew(context, req)

  # compute the signature
  begin
    signature = @signer.sign_request(
      http_method: req.http_method,
      url: req.endpoint,
      headers: req.headers,
      body: req.body
    )
  rescue Aws::Sigv4::Errors::MissingCredentialsError
    # Necessary for when credentials is explicitly set to nil
    raise Aws::Errors::MissingCredentialsError
  end
  # apply signature headers
  req.headers.update(signature.headers)

  # add request metadata with signature components for debugging
  context[:canonical_request] = signature.canonical_request
  context[:string_to_sign] = signature.string_to_sign
end
sign_event(*args) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 154
def sign_event(*args)
  @signer.sign_event(*args)
end

Private Instance Methods

apply_authtype(context, req) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 160
def apply_authtype(context, req)
  # only used for event streaming at input
  if context[:input_event_emitter]
    req.headers['X-Amz-Content-Sha256'] = 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
  elsif unsigned_payload?(context, req)
    req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
  end
end
apply_clock_skew(context, req) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 183
def apply_clock_skew(context, req)
  if context.config.respond_to?(:clock_skew) &&
     context.config.clock_skew &&
     context.config.correct_clock_skew

    endpoint = context.http_request.endpoint
    skew = context.config.clock_skew.clock_correction(endpoint)
    if skew.abs.positive?
      req.headers['X-Amz-Date'] =
        (Time.now.utc + skew).strftime('%Y%m%dT%H%M%SZ')
    end
  end
end
reset_signature(req) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 175
def reset_signature(req)
  # in case this request is being re-signed
  req.headers.delete('Authorization')
  req.headers.delete('X-Amz-Security-Token')
  req.headers.delete('X-Amz-Date')
  req.headers.delete('x-Amz-Region-Set')
end
unsigned_payload?(context, req) click to toggle source
# File lib/aws-sdk-core/plugins/sign.rb, line 169
def unsigned_payload?(context, req)
  (context.operation['unsignedPayload'] ||
    context.operation['authtype'] == 'v4-unsigned-body') &&
    req.endpoint.scheme == 'https'
end