如何使用CloudFront签名Cookie访问S3文件夹下所有资源以搭建HLS流媒体服务
配置方案与示例说明
1 权限配置问题修复
首先你当前遇到的Access Denied首先和对象键拼写错误有关:你实际S3内的视频路径前缀为video/,测试时填写的vides/*、vidos/test.m3u8均为拼写错误,修正前缀后按以下方式配置即可访问整个文件夹下的所有文件:
- 若搭配CloudFront使用Signed Cookie(主流HLS流媒体方案),使用自定义签名策略,将策略中的
Resource字段配置为arn:aws:s3:::<你的S3存储桶名称>/video/*,即可匹配video路径下所有子文件与子目录资源,无需单独指定每个HLS分片文件 - 若直接给S3配置Signed Cookie,签名时的资源字段填写
s3://<你的S3存储桶名称>/video/*即可,同时确保S3桶策略没有额外限制video/前缀的访问权限
2 Signed Cookie 示例代码
以下为Python实现的CloudFront Signed Cookie生成示例:
import datetime import base64 from botocore.signers import CloudFrontSigner from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import padding def rsa_signer(message): # 替换为你本地存储的CloudFront私钥文件路径 with open('cloudfront_private_key.pem', 'rb') as f: private_key = serialization.load_pem_private_key(f.read(), password=None) return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1()) # 替换为你的CloudFront密钥对ID CF_KEY_PAIR_ID = "APKAXXXXXXXXXXXXXX" # 替换为你的CloudFront分发域名下的video路径,匹配该路径下所有资源 CF_RESOURCE_URL = "https://<你的CloudFront分发域名>/video/*" # 签名有效时长,此处设置为24小时 EXPIRE_AT = datetime.datetime.utcnow() + datetime.timedelta(hours=24) signer = CloudFrontSigner(CF_KEY_PAIR_ID, rsa_signer) raw_policy = signer.build_policy(CF_RESOURCE_URL, EXPIRE_AT) raw_signature = signer.sign_policy(raw_policy) # 对策略和签名做URL安全编码 encoded_policy = base64.b64encode(raw_policy.encode("utf-8")).decode("utf-8").replace("+", "-").replace("=", "_").replace("/", "~") encoded_signature = base64.b64encode(raw_signature).decode("utf-8").replace("+", "-").replace("=", "_").replace("/", "~") # 最终返回给客户端的三个签名Cookie signed_cookies = { "CloudFront-Policy": encoded_policy, "CloudFront-Signature": encoded_signature, "CloudFront-Key-Pair-Id": CF_KEY_PAIR_ID }
3 注意事项
- 给客户端设置Cookie时,需要将
Path属性设置为/video/,确保该路径下的所有HLS请求(m3u8索引、ts分片)都会携带签名Cookie - CloudFront分发的对应行为需要开启「Restrict Viewer Access」,并且选择使用Signed Cookies验证
- 建议配置CloudFront OAC/OAI访问S3,关闭S3的公共访问权限,避免源站直接暴露
内容的提问来源于stack exchange,提问作者Changyeon Yoo
相关产品推荐
相关产品推荐

