Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create signed urls for CloudFront with Ruby

History:

  1. I created a key and pem file on Amazon.
  2. I created a private bucket
  3. I created a public distribution and used origin id to connect to the private bucket: works
  4. I created a private distribution and connected it the same as #3 - now I get access denied: expected

I'm having a really hard time generating a url that will work. I've been trying to follow the directions described here: http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?PrivateContent.html

This is what I've got so far... doesn't work though - still getting access denied:

def url_safe(s)
  s.gsub('+','-').gsub('=','_').gsub('/','~').gsub(/\n/,'').gsub(' ','')
end

def policy_for_resource(resource, expires = Time.now + 1.hour)
  %({"Statement":[{"Resource":"#{resource}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires.to_i}}}}]})
end

def signature_for_resource(resource, key_id, private_key_file_name, expires = Time.now + 1.hour)
    policy = url_safe(policy_for_resource(resource, expires))
    key = OpenSSL::PKey::RSA.new(File.readlines(private_key_file_name).join("")) 
    url_safe(Base64.encode64(key.sign(OpenSSL::Digest::SHA1.new, (policy))))
end

def expiring_url_for_private_resource(resource, key_id, private_key_file_name, expires = Time.now + 1.hour)
  sig = signature_for_resource(resource, key_id, private_key_file_name, expires)
  "#{resource}?Expires=#{expires.to_i}&Signature=#{sig}&Key-Pair-Id=#{key_id}"
end

resource = "http://d27ss180g8tp83.cloudfront.net/iwantu.jpeg"
key_id = "APKAIS6OBYQ253QOURZA"
pk_file = "doc/pk-APKAIS6OBYQ253QOURZA.pem"
puts expiring_url_for_private_resource(resource, key_id, pk_file)

Can anyone tell me what I'm doing wrong here?

like image 747
Ben Wiseley Avatar asked Apr 13 '10 19:04

Ben Wiseley


Video Answer


2 Answers

All,

I just created a small gem that can be used to sign CF URLs with Ruby using some of the code from this question:

https://github.com/stlondemand/aws_cf_signer

I will probably be making significant changes to it over the coming weeks as I try to actually use it in my application but wanted to let you all know as you are listed in the attributions section. :)

Thank you!

like image 83
Dylan Vaughn Avatar answered Sep 20 '22 06:09

Dylan Vaughn


remove url_safe before you set policy: policy = policy_for_resource(resource, expires)

according to docs only Base64 should be safe Url-Safe (m) = CharReplace( Base64(m), "+=/", "-_~" )

.. and make sure that CloudFront is configured properly like: http://blog.cloudberrylab.com/2010/03/how-to-configure-private-content-for.html

like image 38
Blaz Lipuscek Avatar answered Sep 21 '22 06:09

Blaz Lipuscek