class Aws::Signature::V4::Signature
Attributes
Your code goes here…
Your code goes here…
Public Class Methods
@param [String] region AWS region @param [String] key_id AWS user key id @param [String] secret_key AWS user secret key
# File lib/aws/signature/v4.rb, line 20 def initialize (region, key_id, secret_key, algorithm: 'AWS4-HMAC-SHA256', content_type: 'application/x-amz-json-1.0', content_type_sign_header: 'application/x-amz-json-1.0,application/x-www-form-urlencoded', t: nil) # calculate date and time @t = t || Time.now.utc @date = @t.strftime('%Y%m%d') @time = @t.strftime('%Y%m%dT%H%M%SZ') # mandatory fields @region = region @key_id = key_id @secret_key = secret_key # optional fields @algorithm = algorithm # content type used as signing header for generating token @content_type_sign_header = content_type_sign_header # final content type sent with service request @content_type = content_type end
Public Instance Methods
Public - generates AWS authentication signature key v4 to use with low level API calls (not using AWS SDKs) This also sets ‘Authorization’ header in the current instance See docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html for reference @param [String] service_name AWS service name e.g. dynamodb @param [String] amz_target AWS service target operation @param [String] http_method HTTP method e.g. POST @param [String] payload HTTP body content @param [String] host HTTP host url @param [String] uri HTTP path after host @return [String] signature string that can be used in Authentication header to allow access to AWS services using APIs
# File lib/aws/signature/v4.rb, line 47 def generate_signature (service_name, amz_target, http_method, payload, host, uri) # remove protocol (http://, https://) from host host = host.sub(/^https?\:\/\/(www.)?/,'') # construct headers # ordering of header values is important, so we reconstruct rather than add new fields @headers = { 'Content-Type': @content_type_sign_header, 'Host': host, 'X-Amz-Date': @time, 'X-Amz-Target': amz_target } # calculate credential scope credential_scope = "#{@date}/#{@region}/#{service_name}/aws4_request" hashed_payload = Digest::hexencode(Digest::SHA256.digest(payload.to_json)).downcase # CanonicalHeaders canonical_headers = @headers.keys.map {|k,v| k.downcase }.join(';') canonical_headers_entry = @headers.map {|k,v| k.to_s.downcase + ':' + v.to_s }.join("\n") # Task 1: Create a Canonical Request For Signature Version 4 # http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html canonical_request = "#{http_method}\n"\ "#{uri}\n"\ "\n"\ "#{canonical_headers_entry}\n"\ "\n"\ "#{canonical_headers}\n"\ "#{hashed_payload}" hashed_canonical_request = Digest::hexencode(Digest::SHA256.digest(canonical_request)).downcase # Task 2: Create a String to Sign for Signature Version 4 # http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html string_to_sign = "#{@algorithm}\n"\ "#{@time}\n"\ "#{credential_scope}\n"\ "#{hashed_canonical_request}" # Task 3: Calculate the AWS Signature Version 4 # http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html signingKey = get_signature_key (service_name) # Task 4: Add the Signing Information to the Request # http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html @signature = Digest::hexencode(OpenSSL::HMAC.digest( OpenSSL::Digest.new('SHA256'),signingKey, string_to_sign)) # generate authorization header and update it in headers generate_authorization_header(service_name, amz_target, http_method, payload, host, uri) @signature end
# File lib/aws/signature/v4.rb, line 100 def get_signature_key (service_name) kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + @secret_key, @date) kRegion = OpenSSL::HMAC.digest('sha256', kDate, @region) kService = OpenSSL::HMAC.digest('sha256', kRegion, service_name) kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request") kSigning end