Access Denied (403) from AWS Cloudfront Application Signed by Cookie on Rails

I tried all day long for this, but I couldn't ...

and. I created a model to create a signed cookie. I need help: spacevatican.org

def cookie_data(resource, expiry)
  raw_policy = policy(resource, expiry)
  {
    'CloudFront-Expires' => expiry.utc.to_i,
    'CloudFront-Signature' => sign(raw_policy),
    'CloudFront-Key-Pair-Id' => ENV['CLOUDFRONT_KEY_PAIR_ID']
  }
end

private

def policy(url, expiry)
  {
     "Statement"=> [
        {
           "Resource" => url,
           "Condition"=>{
              "DateLessThan" =>{"AWS:EpochTime"=> expiry.utc.to_i}
           }
        }
     ]
  }.to_json.gsub(/\s+/,'')
end

def safe_base64(data)
  Base64.strict_encode64(data).tr('+=/', '-_~')
end

def sign(data)
  digest = OpenSSL::Digest::SHA1.new
  key    = OpenSSL::PKey::RSA.new ENV['CLOUDFRONT_PRIVATE_KEY']
  result = key.sign digest, data
  safe_base64(result)
end

      

B. Call cookie_data with 'resource' and 'expiry'. I got randalv help for the correct resource.

base_domain = '.myapp.com' # sample name
cookie_domain: '.myapp.com'

cookie_data("http://#{URI.parse(base_domain).host}/*", 1.hour.from_now).each do |name, value|
  cookies[name] = { value: value, domain: cookie_domain }
end

      

C. Three Cloudfront checks are passed from A and B - 1. Three existing validation cookies and 2. Expiry of existing validation, 3. Decryption of valid validation. I am aware of these three checks because of the error message on invalid request. But in the end, I always get the same message - Access Denied.

There are some suspects.

  • My CNAME Cloudfront is 'img.myapp.com'

    (sample) but my test domain 'http://dev.myapp.com/#/home'

    and this is my local development server (I changed my local hostname).
    So I tried many combinations (base_domain, cookie_domain): (img.myapp.com, .myapp.com), (.myapp.com, .myapp.com), (dev.myapp.com, .myapp.com).
    But everyone denied it.

  • My Cloudfront and S3 settings are the same as randalv . But I mean two things. "Restrict access to bucket" - "NO" in cloud screen source settings. And I am not building CORS config on S3.

+3


source to share


1 answer


I decided on my own. I had three defects and now it works well after fixing them.

First , I changed the expiration date to the policy.

'CloudFront-Expires' => expiry.utc.to_i,

      

to



'CloudFront-Policy' => safe_base64(raw_policy),

      

Actually, I used policy (custom) instead of expiration (canned). During my attempt, I changed. But I don't know why version expiration is not working.

Second , my base_domain is "img.myapp.com" and my cookie_domain is ".myapp.com".

Third . Don't put the bucket name in your final url. A very trivial mistake, but an important one.

+3


source







All Articles