使用 Ruby 为 CloudFront 创建签名 URL

发布于 2024-08-28 17:31:21 字数 1641 浏览 12 评论 0原文

历史记录:

  1. 我在 Amazon 上创建了密钥和 pem 文件。
  2. 我创建了一个私有存储桶
  3. 我创建了一个公共发行版并使用原始 id 连接到私有存储桶:有效
  4. 我创建了一个私有发行版并以与 #3 相同的方式连接它 - 现在我的访问被拒绝:预计

我遇到了一个非常困难的问题是时候生成一个可以使用的 url 了。我一直在尝试遵循此处描述的说明: http:// /docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?PrivateContent.html

这是我到目前为止所得到的...但不起作用 - 仍然被拒绝访问:

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)

谁能告诉我我在这里做错了什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

旧夏天 2024-09-04 17:31:21

所有,

我刚刚创建了一个小 gem,可用于使用以下问题中的一些代码使用 Ruby 对 CF URL 进行签名:

https://github.com/stlondemand/aws_cf_signer

我可能会在未来几周内对其进行重大更改,因为我尝试在我的应用程序中实际使用它,但想让大家知道,因为您已在归因部分。 :)

谢谢你!

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!

单挑你×的.吻 2024-09-04 17:31:21

这是一个老问题,但是关于使用 ruby​​ sdk 签署 cloudfront url 的知识仍然很少,因此添加一些更新的帮助。现在有一个 cloudfront sdk 这使得这变得非常简单:

signer = Aws::CloudFront::UrlSigner.new({
  key_pair_id: "my_key_pair_id"
  private_key_path: "./my_secret.pem" ,
  # Or, you can just provide the contents of the pem as string
  private_key = "--- long private key ---"
})

signed_url = signer.signed_url('http://my-cloudfront-domain.com/my/object/path', expires: 3600) 

This is an old question but there is still very little out there on signing cloudfront urls using the ruby sdk, so adding some updated help. There is now a cloudfront sdk that makes this pretty easy:

signer = Aws::CloudFront::UrlSigner.new({
  key_pair_id: "my_key_pair_id"
  private_key_path: "./my_secret.pem" ,
  # Or, you can just provide the contents of the pem as string
  private_key = "--- long private key ---"
})

signed_url = signer.signed_url('http://my-cloudfront-domain.com/my/object/path', expires: 3600) 
南薇 2024-09-04 17:31:21

在设置策略之前删除 url_safe:
policy = policy_for_resource(resource, expires)

根据文档,

仅 Base64 应该是安全的 Url-Safe (m) = CharReplace( Base64(m), "+=/", "-_~" ) .. 并确保 CloudFront 是正确配置,例如:
http://blog.cloudberrylab.com/ 2010/03/如何配置-private-content-for.html

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

放赐 2024-09-04 17:31:21

是的,将策略保留为 policy = policy_for_resource(resource, expires) 对我有用。

Yep, leaving policy as policy = policy_for_resource(resource, expires) worked for me.

萌酱 2024-09-04 17:31:21

我分叉了 right_aws (他们没有回复我的拉取请求)...我在他们的 acf 库中设置了 cloudfront 私人流媒体和下载: http://github.com/wiseleyb/right_aws

I forked right_aws (they haven't responded to my pull request)... I set up cloudfront private streaming and downloads in their acf library: http://github.com/wiseleyb/right_aws

浅听莫相离 2024-09-04 17:31:21

我同意迪伦的观点。他在签署网址方面做得很好。我有同样的问题。我浏览了文档。有件事我在那里没有找到。当您创建私有发行版时,通常会授予对文件、存储桶等的访问权限...

在分配存储桶策略之前,我遇到了“访问被拒绝”错误。

您可以分配如下策略:

{
    "Version":"2008-10-17",
    "Id":"PolicyForCloudFrontPrivateContent",
    "Statement":[{
            "Sid":" Grant a CloudFront Origin Identity access to support private content",
            "Effect":"Allow",
            "Principal":{
            "CanonicalUser":"here-goes-your-canonical-name-you-attached-to-cloudfront79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be"
            },
            "Action":"s3:GetObject",
            "Resource":"arn:aws:s3:::change-me-to-your-bucketname/*"
        }
    ]
}

I agree with Dylan. He did good work with signing urls. I had the same issue. I went through the docs. There is one thing that I didn't find there. When you create a private distribution, then you usually give access for files, bucket, etc...

I got Access Denied errors until I assigned Bucket Policy.

You can assign policy like:

{
    "Version":"2008-10-17",
    "Id":"PolicyForCloudFrontPrivateContent",
    "Statement":[{
            "Sid":" Grant a CloudFront Origin Identity access to support private content",
            "Effect":"Allow",
            "Principal":{
            "CanonicalUser":"here-goes-your-canonical-name-you-attached-to-cloudfront79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be"
            },
            "Action":"s3:GetObject",
            "Resource":"arn:aws:s3:::change-me-to-your-bucketname/*"
        }
    ]
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文