使用 Ruby 为 CloudFront 创建签名 URL
Posted
技术标签:
【中文标题】使用 Ruby 为 CloudFront 创建签名 URL【英文标题】:Create signed urls for CloudFront with Ruby 【发布时间】:2011-02-07 14:45:39 【问题描述】:历史:
-
我在 Amazon 上创建了一个密钥和 pem 文件。
我创建了一个私有存储桶
我创建了一个公共分配并使用源 ID 连接到私有存储桶:工作
我创建了一个私有发行版并将其连接到与 #3 相同的位置 - 现在我被拒绝访问:预期
我很难生成一个有效的网址。我一直在尝试遵循此处描述的指示: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)
谁能告诉我我在这里做错了什么?
【问题讨论】:
【参考方案1】:在设置策略之前删除 url_safe: policy = policy_for_resource(resource, expires)
根据文档,只有 Base64 应该是安全的 Url-Safe (m) = CharReplace( Base64(m), "+=/", "-_~" )
.. 并确保 CloudFront 配置正确,例如: http://blog.cloudberrylab.com/2010/03/how-to-configure-private-content-for.html
【讨论】:
【参考方案2】:是的,将政策保留为 policy = policy_for_resource(resource, expires)
对我有用。
【讨论】:
【参考方案3】:我分叉了 right_aws(他们没有响应我的拉取请求)...我在他们的 acf 库中设置了云端私有流和下载:http://github.com/wiseleyb/right_aws
【讨论】:
【参考方案4】:全部,
我刚刚创建了一个小 gem,可用于使用此问题中的一些代码使用 Ruby 对 CF URL 进行签名:
https://github.com/stlondemand/aws_cf_signer
我可能会在接下来的几周内对其进行重大更改,因为我尝试在我的应用程序中实际使用它,但我想让大家知道,因为您在归因部分中列出。 :)
谢谢!
【讨论】:
【参考方案5】:我同意迪伦的观点。他在签名网址方面做得很好。我遇到过同样的问题。我浏览了文档。我在那里没有找到一件事。当您创建私有分发时,您通常会授予对文件、存储桶等的访问权限...
在分配存储桶策略之前,我遇到了拒绝访问错误。
您可以分配如下策略:
"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/*"
]
【讨论】:
【参考方案6】:这是一个老问题,但是关于使用 ruby sdk 签署云端 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)
【讨论】:
以上是关于使用 Ruby 为 CloudFront 创建签名 URL的主要内容,如果未能解决你的问题,请参考以下文章
通过 AWS 开发工具包创建签名的 S3 和 Cloudfront URL
创建 CloudFront 分配,仅接受无服务器签名 URL