Amazon S3 和 CloudFront:分步指南
将私有 S3 存储桶连接到 DRM-X 6.0,配置权限受限的 IAM、浏览器 CORS 和 CloudFront HTTPS 分发,并完成上传验证。
1. 了解连接方式#
DRM-X 使用签名请求直接上传到 S3。观众通过 CloudFront 的 HTTPS URL 下载加密媒体。保持 S3 的 Block all public access 启用;CloudFront 通过 Origin Access Control (OAC) 获得限定范围的读取权限。
CloudFront 提供可用于生产环境的 https://….cloudfront.net 域名,自定义域名不是必需项。公共分发允许通过 URL 获取对象字节;正确打包加密的媒体仍由 DRM 控制解密。CORS 不提供授权。本指南使用普通的公共 CDN 分发;若需要面向观众的签名 URL 或 Cookie,需另行集成。
2. 创建您的 S3 存储桶#

- 打开Amazon S3→General purpose buckets→Create bucket。
- 选择一个地区并记录其代码,例如
us-east-1。选择General purpose。如果要求提供命名空间,请在本演练中使用 Global namespace。 - 输入您自己的全局唯一存储桶名称。保持Object Ownership → ACLs disabled (Bucket owner enforced)。
- 选中 Block all public access。您将通过限定范围的策略授予 CloudFront 访问权限。
- 本指南使用 Default encryption → Server-side encryption with Amazon S3 managed keys (SSE-S3)。这是额外的存储加密,不能替代 DRM 打包加密。SSE-KMS 还需要为上传方和 CloudFront 配置 KMS 权限。
- 查看并创建存储桶。不要启用 S3 静态网站托管。
3. 创建权限受限的 IAM 用户和访问密钥#
- 开放IAM → Policies → Create policy → JSON。粘贴下面的策略,替换各处的示例存储桶名称。
- 该示例仅允许
protected/。如果您使用其他基本路径,请更新前缀条件和对象 ARN。对于存储桶根使用,请删除 ListBucket 前缀条件并对对象使用arn:aws:s3:::YOUR_BUCKET/*。 - 保存策略。打开 IAM → Users → Create user,创建没有 AWS Console 访问权限的专用集成用户,并仅附加此策略。
- 打开用户的Security credentials→Access keys→Create access key。选择在 AWS 之外运行的应用程序的用例,然后按照提示进行操作。牢牢保留 Access key ID 和 Secret access key 至 DRM-X。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListProtectedFolder",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::customer-drm-media-example",
"Condition": {
"StringLike": {
"s3:prefix": [
"protected",
"protected/",
"protected/*"
]
}
}
},
{
"Sid": "BucketRegion",
"Effect": "Allow",
"Action": "s3:GetBucketLocation",
"Resource": "arn:aws:s3:::customer-drm-media-example"
},
{
"Sid": "ManageProtectedObjects",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::customer-drm-media-example/protected/*"
}
]
}请勿使用根密钥或 AdministratorAccess。复制使用 GetObject 和 PutObject;没有单独的 s3:CopyObject IAM 操作。重命名也需要 DeleteObject。本指南遵循 DRM-X 当前的访问密钥形式;单独的角色 ARN 并不能替代密钥对。
4. 配置 S3 CORS 用于浏览器上传#
- 打开你的 S3 桶→Permissions。
- 滚动到 Cross-origin resource sharing (CORS) → Edit。
- 粘贴下面的 JSON。公开加密媒体的读取使用 *,上传仍仅允许来自 DRM-X Console。保留现有存储桶中其他必要的规则。
- 选择Save changes。保持 Block Public Access 启用:CORS 不会公开存储桶。
[
{
"AllowedOrigins": [
"https://6.drm-x.com"
],
"AllowedMethods": [
"PUT"
],
"AllowedHeaders": [
"Content-Type",
"x-amz-meta-drmx-sha256"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3600
},
{
"AllowedOrigins": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedHeaders": [
"Range"
],
"ExposeHeaders": [
"ETag",
"Content-Length",
"Content-Range",
"Accept-Ranges"
],
"MaxAgeSeconds": 3600
}
]在 S3 上配置签名上传,并在 S3 和 CloudFront 上配置播放 CORS。在第 5 步的 CloudFront 响应标头策略中使用相同的播放来源。
5. 创建 CloudFront HTTPS 分发 URL#
- 打开 CloudFront → Distributions → Create distribution,使用标准分配。如果 AWS 显示引导流程或套餐选择,请在创建资源前确认并选择适合账号的套餐。
- 选择存储桶的普通 S3 REST origin,不要使用静态网站端点。按照本指南的文件夹映射方式,将 Origin path 留空。
- 选择Origin access control settings (recommended)。创建或选择带有 Sign requests (recommended) 的 OAC。
- 将 viewer protocol policy 设为 Redirect HTTP to HTTPS 或 HTTPS only,允许 GET, HEAD, OPTIONS。上传直接使用 S3 端点,因此 CloudFront 无需允许 PUT。
- 创建 CloudFront 分配。在S3 → 存储桶 → Permissions → Bucket policy → Edit中应用 CloudFront 生成的存储桶策略,并保留其他必需的现有规则。将访问范围限制为该分配的 ARN。下方示例仅允许读取
protected/。 - 打开 CloudFront → Policies → Response headers → Create response headers policy。按下表配置 CORS,并将策略关联到分配的媒体或默认行为。
- 等待部署完成,复制 Distribution domain name。分发 origin 为
https://YOUR_DISTRIBUTION.cloudfront.net。
| Response headers policy 字段 | 值 |
|---|---|
| Access-Control-Allow-Origin | *(公开加密媒体的推荐设置)。如果您在生成器中指定了来源,此处也应使用同一列表。 |
| Access-Control-Allow-Methods | GET, HEAD, OPTIONS |
| Access-Control-Allow-Headers | Range |
| Access-Control-Expose-Headers | ETag, Content-Length, Content-Range, Accept-Ranges |
| Access-Control-Allow-Credentials | 对此公共加密媒体工作流程禁用。 |
| Access-Control-Max-Age | 3600 |
| Origin override | 启用,以便 CloudFront 一致地控制面向观看者的 CORS。 |
对于 OPTIONS 预检,附加托管 CORS-S3Origin 源请求策略。它将 Origin、Access-Control-Request-Method 和 Access-Control-Request-Headers 转发到 S3。最初仅缓存 GET/HEAD,禁用 OPTIONS 缓存。如果您稍后缓存 OPTIONS,请将这些标头包含在其缓存键中并测试不同的播放器来源;单独转发标头不会将其添加到缓存键中。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowThisCloudFrontDistribution",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::customer-drm-media-example/protected/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EEXAMPLE123"
}
}
}
]
}替换示例 account ID、distribution ID 和存储桶名称。SourceArn 必须指向刚创建的分配。如果修改响应头后仍返回旧缓存,请清除相关测试或媒体路径的缓存。
可选:使用 media.example.com
- 请求涵盖您在 US East (N. Virginia)、us-east-1 中的主机名的 ACM 公共证书,并完成 DNS 验证。
- 在 CloudFront 分配的Alternate domain names中添加域名,并关联证书。
- 在您的 DNS 提供商处,创建指向 CloudFront 主机名的 CNAME 或支持的别名。等待 DNS,证书和分发部署。
- 使用
https://media.example.com作为分发 origin。仅添加 DNS CNAME 不够,还必须在 CloudFront 配置域名及证书。
6. 将 Amazon S3 连接到 DRM-X 6.0#
打开Cloud Storage→Connect storage。选择Amazon S3。
| 字段 | 输入什么 |
|---|---|
| Display name | 便于识别的名称,例如 Production S3。 |
| Bucket name | 确切的名称,不含 s3://。 |
| Region | 存储桶的确切 AWS 区域代码。 |
| Protected-content base path | protected,匹配 IAM 和存储桶策略。 |
| Public URL prefix | https://YOUR_DISTRIBUTION.cloudfront.net/protected或https://media.example.com/protected。 |
| Access key ID / Secret access key | 专用的 IAM 用户密钥对。 |
示例使用名为 protected 的文件夹。存储桶名称不会自动成为文件夹。使用本指南的域名直接映射到存储桶方式时,Public URL prefix 必须包含同一存储文件夹,且只出现一次。
Bucket: customer-drm-media-example
Protected-content base path: protected
Public URL prefix: https://media.example.com/protected
File selected for upload: sample.encrypted.bin
Object key in the bucket: protected/sample.encrypted.bin
Preview URL: https://media.example.com/protected/sample.encrypted.bin如需上传到存储桶根目录,将 Protected-content base path 留空,Public URL prefix 只填写分发 origin。除非刻意将存储桶名称用作文件夹,否则不要追加它。使用此映射时保持 CloudFront Origin path 为空。
如果需要,选择默认上传目的地,然后选择Save and verify。 S3 API 主机名不是您的 CloudFront 分发 URL。
* 策略允许来自任何网站的浏览器读取请求;解密仍受 DRM 许可证授权控制。请使用专门存放加密媒体和预定公开资源的存储桶。媒体请求不得携带跨源 Cookie;使用 Cookie 认证的分发方式需要单独配置 CORS。
生成您的 CORS 和匹配的 URL 字段
该工具在您的浏览器中运行。仅输入公共来源;它不要求访问密钥。
- Protected-content base path
- Public URL prefix
- 示例对象键
- 完整 URL 示例
7. 上传文件并验证其是否有效#
- 打开 Cloud Storage,选择此存储目标并单击 Verify location。成功仅表示 DRM-X 服务器可以列出存储桶内容,不能证明写入权限、浏览器 CORS 或公共分发正常。
- 单击 Upload encrypted files,从已有 DRM-X 加密输出包中选择一个小的加密片段。如果没有现成输出包,可使用下方的一次性加密诊断文件。不要上传原始视频或私人文档。
- 等待成功消息。检查文件名和大小是否出现在 Cloud Storage 中。在提供商控制台中的
protected/下找到相同的对象。 - 在浏览器无痕窗口中打开 Preview URL。确认无需登录即可访问已上传的对象,并返回 HTTP 200。
- 在浏览器的 Network 面板中检查播放清单和媒体的响应。默认策略下,
Access-Control-Allow-Origin应为 *;限制来源的策略下,应为播放器的确切来源。直接打开 URL 不能验证 CORS。 - 测试结束后,仅删除本次创建的临时诊断对象。然后按照 Desktop Packager 指南,在 Package content 中选择此存储目标,并上传完整的加密输出包。手动上传单个文件不会注册 Published Content ID。
- 在 Universal Playback Lab 和您的播放器网站上测试已 Published 的内容。验证视频、音频、跳转及所需设备。能下载二进制文件,并不能证明 DRM 播放正常。
没有加密示例?在 Windows 创建一次性测试文件
在您控制的临时文件夹中的 Windows PowerShell 中运行此命令。它使用仅保存在内存中的一次性 AES 密钥对一条简短的非个人消息进行加密。输出是存储诊断,而不是可播放媒体;它不包含 DRM 内容密钥或客户数据。
$samplePath = Join-Path (Get-Location) 'drmx-storage-check.encrypted.bin'
if (Test-Path -LiteralPath $samplePath) { throw 'Choose a new folder; this test file already exists.' }
$aes = [System.Security.Cryptography.Aes]::Create()
try {
$aes.GenerateKey()
$aes.GenerateIV()
$encryptor = $aes.CreateEncryptor()
try {
$bytes = [Text.Encoding]::UTF8.GetBytes('DRM-X disposable storage check')
$encrypted = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
[IO.File]::WriteAllBytes($samplePath, $encrypted)
} finally { $encryptor.Dispose() }
} finally { $aes.Dispose() }
Get-Item -LiteralPath $samplePath | Select-Object Name, Length上传drmx-storage-check.encrypted.bin,验证其大小和 Preview URL,然后将其从存储桶中删除。
curl.exe -I -H "Origin: https://www.example.com" "https://media.example.com/protected/sample.encrypted.bin"替换两个 URL。默认策略应返回 HTTP 200 和 Access-Control-Allow-Origin: *。带有 Range: bytes=0-15 的 GET 请求应返回 HTTP 206 和 Content-Range。保留媒体 MIME 类型:DASH 使用 application/dash+xml,HLS 使用 application/vnd.apple.mpegurl,媒体文件使用各自适当的类型。
8. 排查问题#
| 结果 | 处理方法 |
|---|---|
| 验证通过;浏览器上传失败 | 检查浏览器 Console 和 Network 面板。允许来自 Console 确切 origin 的 PUT CORS,并允许 Content-Type 请求头。检查网络连接,重新尝试以取得新的预签名 URL。 |
| 上传返回 403 | 检查对象写入权限、存储桶/文件夹范围、端点、区域、请求到期和时钟。请勿共享签名的上传 URL。 |
| 上传成功;公共 URL 返回 403 | 检查是否已启用公共分发,以及域名或 CloudFront 分配是否已部署完成。 |
| 公开 URL 返回 404 | 将完整的 URL 与确切的对象键进行比较。检查丢失或重复的文件夹和文件名大小写。 |
| URL 可直接打开,但播放器获取失败 | 检查分发主机的 GET/HEAD CORS。公开加密媒体可使用 *,也可允许播放器的确切来源。清除 CDN 中过期的缓存响应后重试。使用 S3 时,还应检查 CloudFront 响应标头策略。 |
| DRM-X Playback Lab 可以播放,但 Moodle 或 WordPress 报告 Failed to fetch | 检查分发主机的 GET/HEAD CORS。公开加密媒体可使用 *,也可允许播放器的确切来源。清除 CDN 中过期的缓存响应后重试。使用 S3 时,还应检查 CloudFront 响应标头策略。 |
| 下载成功;播放失败 | 检查加密输出包的发布状态、manifest 路径、MIME 类型和 DRM 许可证授权。参见播放故障排查。 |
CloudFront 403:确认 OAC 对请求进行签名,存储桶策略使用正确的分布 ARN 和前缀,并且来源是 S3 REST 端点。保持 S3 Block Public Access 开启。如果您选择 SSE-KMS,请检查 KMS 权限。
官方参考文献#
其他云服务商的设置请参阅云存储设置指南。
DRM-X 6.0