class Aws::Signers::V4
def self.sign(context)
def self.sign(context) new( context.config.credentials, context.config.sigv4_name, context.config.sigv4_region ).sign(context.http_request) end
def authorization(request, datetime)
def authorization(request, datetime) parts = [] parts << "AWS4-HMAC-SHA256 Credential=#{credentials.access_key_id}/#{credential_scope(datetime)}" parts << "SignedHeaders=#{signed_headers(request)}" parts << "Signature=#{signature(request, datetime)}" parts.join(', ') end
def canonical_header_value(value)
def canonical_header_value(value) value.match(/^".*"$/) ? value : value.gsub(/\s+/, ' ').strip end
def canonical_headers(request)
def canonical_headers(request) headers = [] request.headers.each_pair do |k,v| k = k.downcase headers << [k,v] unless k == 'authorization' end headers = headers.sort_by(&:first) headers.map{|k,v| "#{k}:#{canonical_header_value(v.to_s)}" }.join("\n") end
def canonical_request(request)
def canonical_request(request) [ request.http_method, request.endpoint.path, request.endpoint.querystring, canonical_headers(request) + "\n", signed_headers(request), request.headers['X-Amz-Content-Sha256'] ].join("\n") end
def credential_scope(datetime)
def credential_scope(datetime) parts = [] parts << datetime[0,8] parts << region parts << service_name parts << 'aws4_request' parts.join("/") end
def hexdigest(value)
def hexdigest(value) digest = Digest::SHA256.new if value.respond_to?(:read) chunk = nil chunk_size = 1024 * 1024 # 1 megabyte digest.update(chunk) while chunk = value.read(chunk_size) value.rewind else digest.update(value) end digest.hexdigest end
def hexhmac(key, value)
def hexhmac(key, value) OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value) end
def hmac(key, value)
def hmac(key, value) OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value) end
def initialize(credentials, service_name, region)
-
region
(String
) -- The region (e.g. 'us-west-1') the request -
service_name
(String
) -- The name used by the service in -
credentials
(Credentials
) --
def initialize(credentials, service_name, region) @credentials = credentials @service_name = service_name @region = region end
def sign(request)
-
(Seahorse::Client::Http::Request)
- the signed request.
Parameters:
-
request
(Seahorse::Client::Http::Request
) --
def sign(request) datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ") request.headers['X-Amz-Date'] = datetime request.headers['Host'] = request.endpoint.host request.headers['X-Amz-Security-Token'] = credentials.session_token if credentials.session_token request.headers['X-Amz-Content-Sha256'] ||= hexdigest(request.body) request.headers['Authorization'] = authorization(request, datetime) request end
def signature(request, datetime)
def signature(request, datetime) k_secret = credentials.secret_access_key k_date = hmac("AWS4" + k_secret, datetime[0,8]) k_region = hmac(k_date, region) k_service = hmac(k_region, service_name) k_credentials = hmac(k_service, 'aws4_request') hexhmac(k_credentials, string_to_sign(request, datetime)) end
def signed_headers(request)
def signed_headers(request) headers = request.headers.keys headers.delete('authorization') headers.sort.join(';') end
def string_to_sign(request, datetime)
def string_to_sign(request, datetime) parts = [] parts << 'AWS4-HMAC-SHA256' parts << datetime parts << credential_scope(datetime) parts << hexdigest(canonical_request(request)) parts.join("\n") end