无法使用带签名的Cookie访问CloudFront

4

我正在尝试为我的CloudFront分发使用签名cookie。

我正在使用cookie-signer生成签名cookie。以下脚本用于从CloudFront获取文件:

import requests
cookies = {
'CloudFront-Key-Pair-Id': 'APKXXXXXXXXXXX',
'CloudFront-Policy': u'eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kNXRpdXV2ZjdodDlpLmNsb3VkZnJvbnQubmV0L21lZGlhL3Byb2ZpbGVfcGljLmpwZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTQ5Mjc2ODcwMH19fV19',
'CloudFront-Signature': u'ZVG-Pi7x~edJqERf99O9und0wYedB-SHMNKuHd4UpEDaPckYekGoAJ~q8tU0vQI4mS9odXITzAKl4v7tmfDjG1y9FmWaSxgf9h2jrssIk25Mswk3UXOV7wRNs9DiHpA3~D70qAWXGS9GVN4z3SvZ3xQv9bM1P50y2shNPlOCV4o5nAH56sYdvdJNjxSFxdoOUMuhxyrzf-Gv5fjNSzv2Dy43WY6rmpEMfh6L9Eb-2kcrS9p5rsK9MtAwpN8Frobt4bCuduQleb~DXZ~O~hoBGdO3RdyYWgMdTa~02PQl3st8eisBiH7XYy2GbOwPIN~M4m-UAs3ihL0ZWUjbkVDFCA__',
'Secure': 'True',
'HTTPOnly': 'True',

}
headers = {}

s = requests.Session()

res = s.get('http://XXXXXXX.cloudfront.net/media/profile_pic.jpg', 
headers=headers, cookies=cookies)
print res
print res.content

输出:

 <Response [403]>
 <?xml version="1.0" encoding="UTF-8"?>
 <Error><Code>AccessDenied</Code><Message>Access Denied</Message>
 <RequestId>BBDBA8E7FEDA7759</RequestId><HostId>7Pt2/REdiugH5Te555/v004J6skQs9+ccncmXM74yHwPhQrSMJ9pavIj2QmPW6g2QsnnEYGxitc=</HostId></Error>

已将用户添加到云前端分发的可信签署者,并为云前端生成了一个密钥对。

有人能帮我处理这个吗? 先感谢了。

2个回答

2
这个方法对我来说很有效,使用你提供的GitHub gist。过期时间必须以epoch时间(秒)的形式提供,并且传递的URL必须是完整的CloudFront URL(例如:https://example.com/my/s3/object.png)。
import datetime
ex = datetime.datetime.utcnow() + datetime.timedelta(minutes=expire_min)
c = create_signed_cookies(url, int(ex.strftime('%s')))

您的S3存储桶策略需要允许从分配给您的CloudFront分发的CloudFront Origin Access Identity获取对象。

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}

您的密钥对 ID 需要引用您创建的密钥对,就像这样(您必须作为根帐户登录):https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-creating-cloudfront-key-pairs-procedure。请注意保留 HTML 标签。

1
你的错误实际上是S3错误,而不是Cloudfront(CF)错误。你是否创建了一个允许GetObject访问的存储桶策略?
{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/*"]
    }
  ]
}

查看http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html

如果您在CF中使用S3作为源,则需要创建Origin Access Identity,并确保在S3 Bucket策略中授予其访问权限。 (请参见http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-6

如果您正在尝试使用S3静态网页托管服务,则建议在策略中列出Cloudfront IP地址或在CF中添加一个“Origin Custom Header”,例如“referer”,然后在存储桶策略中查找标头。(请参阅http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-4)
作为一项合理性检查,您可能想尝试使用AWS-CLI生成已签名的URL。(请参阅http://docs.aws.amazon.com/cli/latest/reference/cloudfront/sign.html)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接