Rails 支持的应用程序上的 AWS Cloudfront 签名 Cookie 拒绝访问 (403)

Access Denied (403) from AWS Cloudfront Signed Cookie on Rails backed app

我为此试了一整天,但我做不到...

一个。我制作了一个用于创建签名 cookie 的模型。我得到了帮助: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

乙。用 'resource' 和 'expiry' 调用 cookie_data。我从 那里获得了适当资源的帮助。

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

摄氏度。从 A 和 B 中,通过了 Cloudfront 的三个验证 - 1. 三个 cookie 现有验证,以及 2. 现有验证到期,3. 解码可用验证。由于无效请求的错误消息,我知道这三个验证。但毕竟,我总是喜欢同样的信息——访问被拒绝。

有一些嫌疑。

  1. 我的 Cloudfront 的 CNAME 是 'img.myapp.com'(示例),但我的测试域是 'http://dev.myapp.com/#/home',这是我的本地开发服务器(我更改了本地主机名)。
    所以我尝试了 (base_domain, cookie_domain) 的多种组合:(img.myapp.com, .myapp.com), (.myapp.com, .myapp.com ), (dev.myapp.com, .myapp.com).
    但都被拒绝了。

  2. 我的 Cloudfront 和 S3 设置与 上的相同。但我介意两件事。 'Restrict Bucket Access' 在云端的原始设置上是 'NO'。而且我没有在 S3 上创建 CORS 配置。

我自己解决了。 我有3个缺陷,改正后效果很好

首先,我把expires改成了policy。

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

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

实际上,我使用的是 policy(custom) 而不是 expires(canned)。在我尝试的过程中,我改变了。但是不知道为什么expires版本不行

第二个,我的base_domain是'img.myapp.com',cookie_domain是'.myapp.com'.

第三,不要在最后url输入桶名。非常微不足道的错误,但很重要。