限制对 Amazon S3 源的访问 - Amazon CloudFront
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

限制对 Amazon S3 源的访问

将 CloudFront 与作为源的 Amazon S3 存储桶结合使用时,可以按提供以下好处的方式配置 CloudFront 和 Amazon S3:

  • 限制对 Amazon S3 存储桶的访问,使其无法公开访问

  • 确保查看者(用户)只能通过指定的 CloudFront 分配访问存储桶中的内容,也就是说,防止他们直接访问存储桶中的内容,或者通过意外的 CloudFront 分配访问存储桶中的内容

为此,请将 CloudFront 配置为向 Amazon S3 发送经过身份验证的请求,并将 Amazon S3 配置为仅允许访问来自 CloudFront 的经过身份验证的请求。CloudFront 提供两种向 Amazon S3 源发送经身份验证的请求的方式:源访问控制 (OAC) 和源访问身份 (OAI)。我们建议使用 OAC,因为它支持:

  • Amazon Web Services 区域 中的所有 Amazon S3 存储桶,包括 2022 年 12 月之后推出的选择加入区域

  • Amazon S3 使用 Amazon KMS 的服务器端加密 (SSE-KMS)

  • 对 Amazon S3 的动态请求(PUTDELETE

OAI 不适用于前面列表中的场景,或者在这些场景中需要额外的解决方法。以下主题介绍了如何将 OAC 与 Amazon S3 源配合使用。有关如何从 OAI 迁移到 OAC 的信息,请参阅从源访问身份 (OAI) 迁移到源访问控制 (OAC)

注意

如果您的源是配置为网站端点的 Amazon S3 存储桶,则必须使用 CloudFront 将其设置为自定义源。这意味着您无法使用 OAC(或 OAI)。但是,您可以通过设置自定义标头和配置源来要求提供标头,从而限制对自定义源的访问。有关更多信息,请参阅 在自定义源上限制对文件的访问

主题

创建新的源访问控制

完成以下主题中描述的步骤,在 CloudFront 中设置新的源访问控制。

先决条件

在创建和设置源访问控制 (OAC) 之前,您必须拥有带有 Amazon S3 存储桶源的 CloudFront 分配。此源必须是常规 S3 存储桶,而不是配置为网站端点的存储桶。有关设置 CloudFront 分配与 S3 存储桶源配合使用的更多信息,请参阅开始使用简单的 CloudFront 分配

向源访问控制授予访问 S3 存储桶的权限

在创建源访问控制 (OAC) 或在 CloudFront 分配中进行设置之前,请确保 OAC 有权访问 S3 存储桶源。请在创建 CloudFront 分配后,但在分配配置中将 OAC 添加到 S3 源之前,执行此操作。

要授予 OAC 访问 S3 存储桶的权限,请使用 S3 存储桶策略,以允许 CloudFront 服务主体 (cloudfront.amazonaws.com) 访问存储桶。使用策略中的 Condition 元素,仅在请求代表包含 S3 源的 CloudFront 分配时,才允许 CloudFront 访问存储桶。

有关添加或修改存储桶策略的信息,请参阅 Amazon S3 用户指南 中的使用 Amazon S3 控制台添加存储桶策略

以下是允许 CloudFront OAC 访问 S3 源的 S3 存储桶策略示例。在以下示例中:

  • DOC-EXAMPLE-BUCKET 替换为 S3 存储桶源的名称

  • 111122223333 替换为包含 CloudFront 分配和 S3 存储桶源的 Amazon Web Services 账户 ID

  • EDFDVBD6EXAMPLE 替换为 CloudFront 分配的 ID

例 允许对 CloudFront OAC 进行只读访问的 S3 存储桶策略

{ "Version": "2012-10-17", "Statement": { "Sid": "AllowCloudFrontServicePrincipalReadOnly", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } } }

例 允许对 CloudFront OAC 进行读写访问的 S3 存储桶策略

{ "Version": "2012-10-17", "Statement": { "Sid": "AllowCloudFrontServicePrincipalReadWrite", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } } }

SSE-KMS

如果 S3 存储桶源中的对象是通过采用 Amazon Key Management Service 的服务器端加密 (SSE-KMS) 进行加密的,您必须确保 OAC 有权使用 Amazon KMS 密钥。要向 OAC 授予使用 KMS 密钥的权限,请向 KMS 密钥策略添加一条语句。有关如何修改密钥策略的信息,请参阅 Amazon Key Management Service 开发人员指南 中的更改密钥策略

以下示例显示了允许 OAC 使用 KMS 密钥的 KMS 密钥策略语句。在以下示例中:

  • 111122223333 替换为包含 CloudFront 分配、S3 存储桶源和 KMS 密钥的 Amazon Web Services 账户 ID

  • EDFDVBD6EXAMPLE 替换为 CloudFront 分配的 ID

例 允许 CloudFront OAC 访问 SSE-KMS 的 KMS 密钥的 KMS 密钥策略语句

{ "Sid": "AllowCloudFrontServicePrincipalSSE-KMS", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root", "Service": "cloudfront.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey*" ], "Resource": "*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } }

创建源访问控制

要创建源访问控制 (OAC),可以使用 Amazon Web Services Management Console、Amazon CloudFormation、Amazon CLI 或 CloudFront API。

Console

创建源访问控制

  1. 登录 Amazon Web Services Management Console,并通过以下网址打开 CloudFront 控制台:https://console.amazonaws.cn/cloudfront/v3/home

  2. 在导航窗格中,选择 Origin access(源访问)。

  3. 选择 Create control setting(创建控制设置)。

  4. Create control setting(创建控制设置)表单上,执行以下操作:

    1. Details(详细信息)窗格中,输入源访问控制的 Name(名称)和(可选)Description(描述)。

    2. Settings(设置)中,建议保留默认设置 [Sign requests (recommended)(签署请求(推荐))]。有关更多信息,请参阅源访问控制的高级设置

  5. 选择 Create (创建)

    创建 OAC 后,记下 Name(名称)。在以下过程中,您需要此名称。

向分配中的 S3 源添加源访问控制

  1. 通过 打开 CloudFront 控制台https://console.amazonaws.cn/cloudfront/v3/home

  2. 选择具有要向其添加 OAC 的 S3 源的分配,然后选择 Origins(源)选项卡。

  3. 选择要向其添加 OAC 的 S3 源,然后选择 Edit(编辑)。

  4. Origin access(源访问)部分,选择 Origin access control settings (recommended) [源访问控制设置(推荐)]。

  5. Origin access control(源访问控制)下拉菜单中,选择要使用的 OAC。

  6. 选择保存更改

分配开始部署到所有 CloudFront 边缘站点。当边缘站点收到新配置时,它会签署其发送到 S3 存储桶源的所有请求。

CloudFormation

要使用 Amazon CloudFormation 创建源访问控制 (OAC),请使用 AWS::CloudFront::OriginAccessControl 资源类型。以下示例显示了 YAML 格式的 Amazon CloudFormation 模板语法,用于创建源访问控制。

Type: AWS::CloudFront::OriginAccessControl Properties: OriginAccessControlConfig: Description: An optional description for the origin access control Name: ExampleOAC OriginAccessControlOriginType: s3 SigningBehavior: always SigningProtocol: sigv4

有关更多信息,请参阅 Amazon CloudFormation 用户指南 中的 AWS::CloudFront::OriginAccessControl

CLI

要使用 Amazon Command Line Interface (Amazon CLI) 创建源访问控制,请使用 aws cloudfront create-origin-access-control 命令。您可以使用输入文件来提供命令的输入参数,而不是将每个单独的参数指定为命令行输入。

创建源访问控制(带输入文件的 CLI)

  1. 使用以下命令创建名为 origin-access-control.yaml 的文件。此文件包含 create-origin-access-control 命令的所有输入参数。

    aws cloudfront create-origin-access-control --generate-cli-skeleton yaml-input > origin-access-control.yaml
    注意

    yaml-input 选项仅适用于 Amazon CLI 版本 2。利用版本 1 的 Amazon CLI,您可以生成 JSON 格式的输入文件。有关更多信息,请参阅 Amazon Command Line Interface 用户指南中的从 JSON 或 YAML 输入文件生成 Amazon CLI 骨架和输入参数

  2. 打开刚创建的 origin-access-control.yaml 文件。编辑文件以添加 OAC 的名称、描述(可选),然后将 SigningBehavior 更改为 always。然后保存文件。

    有关其他 OAC 设置的信息,请参阅源访问控制的高级设置

  3. 使用以下命令通过 origin-access-control.yaml 文件中的输入参数创建源访问控制。

    aws cloudfront create-origin-access-control --cli-input-yaml file://origin-access-control.yaml

    记下命令输出中的 Id 值。您需要使用它将 OAC 添加到 CloudFront 分配中的 S3 存储桶源。

将 OAC 附加到现有分配中的 S3 存储桶源(带输入文件的 CLI)

  1. 使用以下命令保存要向其添加 OAC 的 CloudFront 分配的分配配置。该分配必须有 S3 存储桶源。将 distribution_ID 替换为分配 ID。

    aws cloudfront get-distribution-config --id distribution_ID --output yaml > dist-config.yaml
    注意

    --output yaml 选项仅适用于 Amazon CLI 版本 2。利用版本 1 的 Amazon CLI,您可以生成 JSON 格式的输出。有关更多信息,请参阅 Amazon Command Line Interface 用户指南中的从 Amazon CLI 控制命令输出

  2. 打开刚创建的名为 dist-config.yaml 的文件。编辑文件,进行以下更改:

    • Origins 对象中,将 OAC 的 ID 添加到名为 OriginAccessControlId 的字段中。

    • 从名为 OriginAccessIdentity 的字段中移除值(如果存在)。

    • ETag 字段重命名为 IfMatch,但不更改字段的值。

    完成后保存该文件。

  3. 使用以下命令更新分配以使用源访问控制。将 distribution_ID 替换为分配 ID。

    aws cloudfront update-distribution --id distribution_ID --cli-input-yaml file://dist-config.yaml

分配开始部署到所有 CloudFront 边缘站点。当边缘站点收到新配置时,它会签署其发送到 S3 存储桶源的所有请求。

API

要使用 CloudFront API 创建源访问控制,请使用 CreateOriginAccessControl。有关您在此 API 调用中指定的字段的更多信息,请参阅 Amazon 开发工具包或其他 API 客户端的 API 参考文档。

创建源访问控制后,可以使用下面的任何一个 API 调用将其附加到分配中的 S3 存储桶源:

对于这两个 API 调用,请在源内的 OriginAccessControlId 字段中提供源访问控制 ID。有关您在这些 API 调用中指定的其他字段的更多信息,请参阅 您创建或更新分配时指定的值 以及 Amazon 开发工具包或其他 API 客户端的 API 参考文档。

从源访问身份 (OAI) 迁移到源访问控制 (OAC)

要从旧式源访问身份 (OAI) 迁移到源访问控制 (OAC),请先更新 S3 存储桶源以允许 OAI 和 OAC 访问存储桶的内容。这可确保 CloudFront 在过渡期间不会丢失对存储桶的访问权限。要允许 OAI 和 OAC 访问 S3 存储桶,请更新存储桶策略以包括两个语句,每种主体一个。

以下示例 S3 存储桶策略允许 OAI 和 OAC 访问 S3 源。在以下示例中:

  • DOC-EXAMPLE-BUCKET 替换为 S3 存储桶源的名称

  • 111122223333 替换为包含 CloudFront 分配和 S3 存储桶源的 Amazon Web Services 账户 ID

  • EDFDVBD6EXAMPLE 替换为 CloudFront 分配的 ID

  • EH1HDMB1FH2TC 替换为源访问身份的 ID

例 允许对 OAI 和 OAC 进行只读访问的 S3 存储桶策略

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipalReadOnly", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } }, { "Sid": "AllowLegacyOAIReadOnly", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" } ] }

在更新 S3 源的存储桶策略以允许访问 OAI 和 OAC 之后,您可以更新分配配置以使用 OAC(而不是 OAI)。有关更多信息,请参阅创建新的源访问控制

完全部署分配后,您可以删除存储桶策略中允许访问 OAI 的语句。有关更多信息,请参阅向源访问控制授予访问 S3 存储桶的权限

源访问控制的高级设置

CloudFront 源访问控制功能包括仅适用于特定用例的高级设置。除非您特别需要高级设置,否则请使用推荐的设置。

源访问控制包含一个名为 Signing behavior(签名行为)(在控制台中)或 SigningBehavior(在 API、CLI 和 Amazon CloudFormation)的设置。此设置提供以下选项:

始终签署源请求(推荐设置)

我们建议使用此设置,此设置在控制台中名为 Sign requests (recommended) [签署请求(推荐)],在 API、CLI 和 Amazon CloudFormation 中名为 always。使用此设置,CloudFront 将始终签署其发送到 S3 存储桶源的所有请求。

切勿签署源请求

此设置在控制台中名为 Do not sign requests(请勿签署请求),在 API、CLI 和 Amazon CloudFormation 中名为 never。使用此设置关闭所有使用此源访问控制的分配中所有源的源访问控制。与从所有使用源访问控制的源和分配中逐一删除源访问控制相比,这可以节省时间和精力。使用此设置,CloudFront 不会签署其发送到 S3 存储桶源的任何请求。

警告

要使用此设置,S3 存储桶源必须可公开访问。如果您将此设置用于不可公开访问的 S3 存储桶源,则 CloudFront 无法访问该源。S3 存储桶源向 CloudFront 返回错误,而 CloudFront 会将这些错误传递给查看者。

不要改写查看器(客户端)Authorization 标头

此设置在控制台中名为 Do not override authorization header(请勿改写授权标头),在 API、CLI 和 Amazon CloudFormation 中名为 no-override。如果您希望 CloudFront 仅在相应的查看器请求不包含 Authorization 标头时签署源请求,请使用此设置。使用此设置,CloudFront 会在查看器请求中存在 Authorization 标头时传递该标头,但在查看器请求不包含 Authorization 标头时对源请求进行签名(添加自己的 Authorization 标头)。

警告

要传递查看器请求的 Authorization 标头,您必须 针对所有使用与此源访问控制关联的 S3 存储桶源的缓存行为将 Authorization 标头添加到缓存策略中。

使用源访问身份(旧版,不推荐)

CloudFront 源访问身份 (OAI) 提供与源访问控制 (OAC) 类似的功能,但它并不适用于所有场景。这就是为什么我们建议改用 OAC 的原因。具体而言,OAI 不支持:

  • 所有 Amazon Web Services 区域中的 Amazon S3 存储桶,包括可选择加入的区域

  • Amazon S3 使用 Amazon KMS 的服务器端加密 (SSE-KMS)

  • 对 Amazon S3 的动态请求(PUTPOSTDELETE

  • 2022 年 12 月之后推出的新 Amazon Web Services 区域

有关如何从 OAI 迁移到 OAC 的信息,请参阅从源访问身份 (OAI) 迁移到源访问控制 (OAC)

当您使用 CloudFront 控制台创建 OAI 或将 OAI 添加到分配时,可以自动更新 Amazon S3 存储桶策略以向 OAI 提供访问存储桶的权限。您也可以选择手动创建或更新存储桶策略。无论使用哪种方法,您仍应查看权限,从而确保:

  • 您的 CloudFront OAI 可以代表通过 CloudFront 发出请求的查看器来访问存储桶中的文件。

  • 查看者不能使用 Amazon S3 URL 访问位于 CloudFront 外部的文件。

重要

如果您将 CloudFront 配置为接受并转发 CloudFront 支持的所有 HTTP 方法,请确保为您的 CloudFront OAI 授予所需的权限。例如,假设您将 CloudFront 配置为接受和转发使用 DELETE 方法的请求,则配置您的存储桶策略以适当地处理 DELETE 请求,从而确保查看器只能删除您希望它们删除的文件。

使用 Amazon S3 存储桶策略

您可以通过以下方式创建或更新 Amazon S3 存储桶策略,向 CloudFront OAI 授予对该存储桶中文件的访问权限:

  • 使用 Amazon S3 控制台中 Amazon S3 存储桶的 Permissions(权限)选项卡。

  • 使用 Amazon S3 API 中的 PutBucketPolicy

  • 使用 CloudFront 控制台。在 CloudFront 控制台中向源设置添加 OAI 时,您可以选择 Yes, update the bucket policy(是,更新存储桶策略),从而让 CloudFront 代表您更新存储桶策略。

如果您手动更新存储桶策略,请务必:

  • 在策略中指定正确的 OAI 为 Principal

  • 授予 OAI 所需的权限以便代表查看器访问对象。

有关更多信息,请参阅以下部分。

在存储桶策略中将 OAI 指定为 Principal

要在 Amazon S3 存储桶策略中将 OAI 指定为 Principal,请使用 OAI 的 Amazon 资源名称 (ARN),其中包括 OAI 的 ID。例如:

"Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC" }

要使用上述示例,请将 EH1HDMB1FH2TC 替换为 OAI 的 ID。要查找 OAI 的 ID,请查看 CloudFront 控制台中的源访问身份页面,或者使用 CloudFront API 中的 ListCloudFrontOriginAccessIdentities

向 OAI 授予权限

要向 OAI 授予对 Amazon S3 存储桶中对象的访问权限,请使用策略中与特定 Amazon S3 API 操作相关的操作。例如,s3:GetObject 操作允许 OAI 读取存储桶中的对象。有关更多信息,请参阅下一部分的示例,或者参阅《Amazon Simple Storage Service 用户指南》中的 Amazon S3 操作

Amazon S3 存储桶策略示例

以下示例显示了允许 CloudFront OAI 访问 S3 存储桶的 Amazon S3 存储桶策略。在使用这些示例时:

例 向 OAI 授予读取访问权限的 Amazon S3 存储桶策略

下面的示例允许 OAI 读取指定存储桶 (s3:GetObject) 中的对象。

{ "Version": "2012-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" } ] }

例 向 OAI 授予读写访问权限的 Amazon S3 存储桶策略

下面的示例允许 OAI 读取和写入指定存储桶(s3:GetObjects3:PutObject)中的对象。这允许查看器通过 CloudFront 将文件上传到您的 Amazon S3 存储桶。

{ "Version": "2012-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC" }, "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" } ] }

使用 Amazon S3 对象 ACL(不建议)

重要

我们建议使用 Amazon S3 存储桶策略向 OAI 提供对 S3 存储桶的访问权限。您也可以按照这一部分的描述使用 ACL,但我们不建议您这样做。

Amazon S3 建议将 bS3 Object Ownership(S3 对象所有权)设置为 bucket owner enforced(强制执行存储桶拥有者),这意味着存储桶以及其中的对象禁用 ACL。当您应用此对象所有权设置后,必须使用存储桶策略向 OAI 授予访问权限(请参阅上一部分)。

以下部分仅适用于需要 ACL 的传统使用案例。

您可以通过以下方式创建或更新文件的 ACL,向 CloudFront OAI 授予对 Amazon S3 存储桶中文件的访问权限:

使用 ACL 向 OAI 授予访问权限时,您必须使用其 Amazon S3 规范用户 ID 来指定 OAI。这是 CloudFront 控制台的源访问身份页面上 Amazon S3 canonical user ID(Amazon S3 规范用户 ID)的值。如果使用 CloudFront API,请使用您在创建 OAI 时返回的 S3CanonicalUserId 元素值,或者调用 CloudFront API 中的 ListCloudFrontOriginAccessIdentities

较新的 Amazon S3 区域要求对通过身份验证的请求使用签名版本 4。(有关各个 Amazon S3 区域支持的签名版本,请参阅《Amazon一般参考》中的 Amazon Simple Storage Service 端点和配额。) 如果您使用源访问身份并且存储桶位于要求使用签名版本 4 的区域之一,请注意以下几点:

  • 支持 DELETEGETHEADOPTIONSPATCH 请求,无限定条件。

  • 如果要向 CloudFront 提交 PUT 请求以将文件上传到 Amazon S3 存储桶,您必须在请求中添加 x-amz-content-sha256 标头。标头值必须包含请求正文的 SHA-256 哈希值。有关更多信息,请参阅《Amazon Simple Storage Service API 参考》中的常见请求标头页面上有关 x-amz-content-sha256 标头的文档。

  • 不支持 POST 请求。