[英]boto3: generate wildcard CloudFront presigned URL
I'm serving some private HLS content with CloudFront, stored in a S3 bucket.我正在使用 CloudFront 提供一些存储在 S3 存储桶中的私有 HLS 内容。 All the HLS content is stored in a
/hls/
directory at the root of my bucket.所有 HLS 内容都存储在我的存储桶根目录下的
/hls/
目录中。
I'm using this code for generating a /hls/*
(note the *
wildcard) pre-signed URL to access (the otherwise inaccessible) content:我正在使用此代码生成
/hls/*
(注意*
通配符)预签名 URL 以访问(否则无法访问)内容:
import datetime
from botocore.signers import CloudFrontSigner
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from my_django_project.settings import (
AWS_CLOUDFRONT_DOMAIN_NAME,
AWS_CLOUDFRONT_KEY_ID,
AWS_CLOUDFRONT_KEY_PATH,
)
def rsa_signer(message):
with open(AWS_CLOUDFRONT_KEY_PATH, "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(), password=None, backend=default_backend()
)
return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())
def get_signed_url():
key_id = AWS_CLOUDFRONT_KEY_ID
url = f"https://{AWS_CLOUDFRONT_DOMAIN_NAME}/hls/*"
expire_datetime = datetime.datetime.now() + datetime.timedelta(minutes=5)
cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)
signed_url = cloudfront_signer.generate_presigned_url(
url,
date_less_than=expire_datetime,
)
return signed_url
This code effectively generates a URL but CloudFront responds with a 403 Access Denied error when I try to access the https://{AWS_CLOUDFRONT_DOMAIN_NAME}/hls/index.m3u8
URL (which is one of the files stored in the /hls/
directory).此代码有效地生成了一个 URL,但当我尝试访问
https://{AWS_CLOUDFRONT_DOMAIN_NAME}/hls/index.m3u8
URL(它是存储在/hls/
目录中的文件之一)时,CloudFront 以 403 Access Denied 错误响应.
I have checked that I am following every guideline for configuring CloudFront and S3 for serving private content with pre-signed URLs.我已经检查过我是否遵循了配置 CloudFront 和 S3 以提供带有预签名 URL 的私有内容的所有指南。 I am starting to suspect that this wildcard thing is the problem.
我开始怀疑这个通配符是问题所在。
I am not sure what I can do to solve the issue.我不确定我能做些什么来解决这个问题。 Any idea?
任何的想法?
You need to be working in UTC timezone.您需要在 UTC 时区工作。 Replace
datetime.datetime.now()
with datetime.datetime.utcnow()
and it should work properly.更换
datetime.datetime.now()
与datetime.datetime.utcnow()
它应该正常工作。
If you are using HLS, you cannot used presignedUrl, you must use a preSigned cookie:如果您使用 HLS,则不能使用 presignedUrl,您必须使用 preSigned cookie:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-choosing-signed-urls-cookies.html https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-choosing-signed-urls-cookies.html
Use signed cookies in the following cases:
You want to provide access to multiple restricted files, for example, all of the files for a video in HLS format or all of the files in the subscribers' area of website.
You don't want to change your current URLs.
PreSignedUrl is only for accessing a specific file, so it does not work for HLS. PreSignedUrl 仅用于访问特定文件,因此它不适用于 HLS。 You will have to specify a custom policy that includes the url you defined:
您必须指定一个包含您定义的 url 的自定义策略:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-canned-policy.html https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-canned-policy.html
Here's some example code I found elsewhere on Stack Overflow that does this all in Python (since the example code from CF doesn't show this level of detail): Creating Signed URLs for Amazon CloudFront Although I ended up doing a hybrid;下面是我在 Stack Overflow 的其他地方找到的一些示例代码,它们全部使用 Python 完成(因为来自 CF 的示例代码没有显示这种详细程度): 为 Amazon CloudFront 创建签名 URL虽然我最终做了一个混合; I used the key/signing handling from the rsa_signer function in the canned policy example from Amazon in place of the sign_string function in the example I linked.
我使用来自 Amazon 的罐头策略示例中的 rsa_signer 函数的密钥/签名处理代替了我链接的示例中的 sign_string 函数。
HOWEVER, if you want to use wildcards, be sure to make it a custom policy by including the base64-encoded policy statement thing as Policy=$policy in your signed url between Expires and Signature, as specified in the link Marc posted.但是,如果您想使用通配符,请确保将 base64 编码的策略声明内容作为 Policy=$policy 包含在 Expires 和 Signature 之间的签名 URL 中,使其成为自定义策略,如 Marc 发布的链接中所述。 I didn't originally read the docs closely enough and was getting pretty frustrated until I went back and read more carefully and included this.
我最初没有足够仔细地阅读文档并且感到非常沮丧,直到我回去更仔细地阅读并将其包含在内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.