Amazon S3 Query String Authentication and Ruby on Rails

Amazons S3 added this summer a new way to allow people to access your files stored on S3. This method is called Query String Authentication and by generating an url for a private file you can offer access to that file for a limited amount of time. First upload a file to Amazon S3 and use the acl ‘private’ to store the file. To generate the url for to such a link I’ve made a helper for Ruby on Rails:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def generateTemporaryURL(resource)
  filename = "#{RAILS_ROOT}/config/amazon_s3.yml"
  config = YAML.load_file(filename)
  bucket = config[ENV['RAILS_ENV']]['bucket_name']
  access_key_id = config[ENV['RAILS_ENV']]['access_key_id']
  secret_access_key = config[ENV['RAILS_ENV']]['secret_access_key']
  expires = 10.days.from_now.to_i # 10 days from now in epoch time in UTC

  stringtosign = "GET\n\n\n#{expires}\n/#{bucket}/"+ENV['RAILS_ENV']+"/#{resource.gsub(" ", "+")}";

  signature = Base64.encode64(
                OpenSSL::HMAC.digest(
                  OpenSSL::Digest::Digest.new('sha1'),
                  secret_access_key, stringtosign.toutf8))
  # cleanup the signature for the url
  signature = signature.gsub("\n","").gsub("+","%2B")

  return "http://#{bucket}/"+ENV['RAILS_ENV']+"/#{resource.gsub(" ", "+")}?AWSAccessKeyId=#{access_key_id}&Expires=#{expires}&Signature=#{signature}"
end

This method generates an url which is valid for 10 days. I’m now 100% sure of the gsub method to convert spaces in a resource filename to a plus sign, maybe there are more characters you should be aware of. Anyway this method is based on the SWF Upload post.

Update: Thanks to Simon, I’ve updated the example where it would produce an invalid signature. The plus sign in the url needs to be url encoded.

Update 2: Rob provided a Ruby 1.9 only version.

Comments

Copyright © 2013 - Tom Pesman - Powered by Octopress