使用源访问身份限制对 Amazon S3 内容的访问 - Amazon CloudFront

使用源访问身份限制对 Amazon S3 内容的访问

要限制对您通过 Amazon S3 存储桶提供的内容的访问,请执行以下步骤:

  1. 创建一个称为源访问身份 (OAI) 的特殊 CloudFront 用户,并将该用户与您的分配相关联。

  2. 配置 S3 存储桶权限,以便 CloudFront 能够使用 OAI 访问存储桶中的文件并将这些文件提供给您的用户。确保用户无法使用 S3 存储桶的直接 URL 访问该存储桶中的文件。

执行完这些步骤后,用户只能通过 CloudFront 访问您的文件,而无法直接从 S3 存储桶访问您的文件。

通常而言,如果您使用 Amazon S3 存储桶作为 CloudFront 分配的源,则可以允许每个人有权访问这些文件,也可以限制访问。例如,如果您通过使用 CloudFront 签名 URL 或签名 Cookie 来限制访问,则您也不会希望人员仅使用该文件的直接 Amazon S3 URL 即可查看文件。相反,您希望他们只能通过使用 CloudFront URL 访问文件,以便您的保护起作用。有关使用签名 URL 和签名 Cookie 的详细信息,请参阅使用签名 URL 和签名 Cookie 提供私有内容

本主题详细介绍了如何设置 OAI 和授予权限以维护对 S3 文件的安全访问。

重要

如果您使用配置为网站终端节点的 Amazon S3 存储桶,则必须使用 CloudFront 将其设置为自定义源。您无法使用本主题中描述的源访问身份功能。但是,您可以 通过设置自定义标头和配置源来要求提供标头,限制对自定义源上内容的访问。有关更多信息,请参阅 在自定义源上限制对文件的访问

OAI 设置概述

当您首次将 Amazon S3 存储桶设置为 CloudFront 分配的源时,将授予每个人读取您存储桶中的文件的权限。这使得任何人都可通过 CloudFront 或使用 Amazon S3 URL 访问您的对象。CloudFront 不公开 Amazon S3 URL,但如果应用程序从 Amazon S3 中直接提供任何文件,或有人泄露了 Amazon S3 中特定文件的直接链接,那么用户可能会拥有这些 URL。

如果使用 CloudFront 签名 URL 或签名 Cookie 来限制对 Amazon S3 存储桶中文件的访问权,您可能还需要防止用户使用 Amazon S3 URL 访问 Amazon S3 文件。如果用户直接在 Amazon S3 中访问您的文件,他们会绕过 CloudFront 签名 URL 或签名 Cookie 所提供的控制。这包括对用户无法再访问内容的日期和时间的控制,以及对可用于访问内容的 IP 地址的控制。此外,如果用户同时通过 CloudFront 和直接使用 Amazon S3 URL 访问文件,则 CloudFront 访问日志将不完整,因此用处不大。

要确保您的用户只使用 CloudFront URL 访问您的文件,无论此 URL 是否签名,请执行以下操作:

  1. 创建源访问身份(一个特殊的 CloudFront 用户),并将源访问身份与分配相关联。您需要将源访问身份与源关联起来,以便您可以保护您的所有 Amazon S3 内容或者只保护其中一部分内容。您也可在创建分配时创建源访问身份并将其添加到您的分配中。有关更多信息,请参阅 创建 CloudFront OAI 并将其添加到您的分配中

  2. 更改对您的 Amazon S3 存储桶或存储桶中文件的权限,以便只有源访问身份具有读取权限(或读取和下载权限)。当用户通过 CloudFront 访问 Amazon S3 文件时,CloudFront 源访问身份将代表用户获取文件。如果用户直接通过使用 Amazon S3 URL 请求文件,他们将会被拒绝访问。源访问身份有权访问 Amazon S3 存储桶中的文件,但用户不能。有关更多信息,请参阅 授予 OAI 读取 Amazon S3 存储桶中文件的权限

创建 CloudFront OAI 并将其添加到您的分配中

一个AWS账户最多可以拥有 100 个 CloudFront 源访问身份 (OAI)。但是,您可以根据需要将 OAI 添加到任意数量的分配中,因此一个 OAI 通常就足够了。

如果在创建分配时未创建 OAI 并将其添加到您的分配中,您现在可以使用 CloudFront 控制台或 CloudFront API 创建并添加一个 OAI:

注意

要创建 OAI,您必须使用 CloudFront 控制台或 CloudFront API 版本 2009-09-09 或更高版本。

创建 OAI 并将其添加到您的分配

如果您在创建分配时未创建 OAI,请执行以下操作。

使用 CloudFront 控制台创建 CloudFront OAI

  1. 登录到 AWS Management Console 并通过 https://console.aws.amazon.com/cloudfront/打开 CloudFront 控制台。

  2. 选择具有 S3 源的分配的 ID。

  3. 选择 Origins and Origin Groups (源和源组) 选项卡。

  4. 选中源旁边的复选框,然后选择 Edit (编辑)

  5. Restrict Bucket Access (限制存储桶访问) 选择

  6. 如果您已有要使用的 OAI,请选择 Use an Existing Identity (使用现有身份)。然后在 Your Identities (您的身份) 列表中选择 OAI。

    注意

    如果您已经拥有 OAI,我们建议您重复使用它以简化维护。

    如果要创建 OAI,请选择 Create a New Identity (创建新身份)。可以将 Comment (注释) 字段中的存储桶名称替换为自定义的描述。

  7. 如果您希望 CloudFront 自动提供读取在源域名中指定的 Amazon S3 存储桶中文件的 OAI 权限,请单击是,更新存储桶策略

    重要

    如果您选择是,更新存储桶策略,CloudFront 将更新存储桶权限,以授予指定的 OAI 读取存储桶中文件的权限。但是,CloudFront 不会删除现有权限。如果用户目前具有使用 Amazon S3 URL 访问存储桶中文件的权限,在 CloudFront 更新存储桶权限后,他们仍具有该权限。要查看或删除现有存储桶权限,使用 Amazon S3 提供的方法。

    如果您希望手动更新对 Amazon S3 存储桶的权限,选择否,我将更新权限。有关更多信息,请参阅授予 OAI 读取 Amazon S3 存储桶中文件的权限

  8. 选择是,编辑

  9. 如果您有多个源,请重复这些步骤以为每个源添加 OAI。

使用 CloudFront API 创建 OAI

如果您已经具有一个源访问身份并要重新使用它,而不是另外创建一个,请跳到 使用 CloudFront API 向您的分配添加 OAI

要使用 CloudFront API 创建 CloudFront OAI,请使用 POST Origin Access Identity API 操作。对于新的 OAI,响应包括一个 Id 和一个 S3CanonicalUserId。记录这些值,因为在该过程的稍后部分中会用到它们:

  • Id 元素 – 您使用 Id 元素的值将 OAI 与您的分配关联起来。

  • S3CanonicalUserId 元素 – 当您使用 Amazon S3 对象 ACL 授予对于 Amazon S3 对象的 OAI 访问权限时,可以使用 S3CanonicalUserId 元素的值。

有关更多信息,请参阅《Amazon CloudFront API 参考》中的 CreateCloudFrontOriginAccessIdentity

使用 CloudFront API 向您的分配添加 OAI

您可以使用 CloudFront API 将 CloudFront OAI 添加到现有分配或创建包含 OAI 的新分配。在这两种情况下,都包括OriginAccessIdentity元素。该元素包含您创建 OAI 时 POST Origin Access Identity API 操作返回的 Id 元素的值。您可以将 OriginAccessIdentity 元素添加到一个或多个源中。

请参阅《Amazon CloudFront API 参考》中的以下主题:

授予 OAI 读取 Amazon S3 存储桶中文件的权限

当您创建或更新分配时,可以添加源访问身份y (OAI) 并自动更新 Amazon S3 存储桶策略,以便为 OAI 提供访问存储桶的权限。或者,您可以选择手动创建或更新存储桶策略,或者使用对象 ACL 来控制对存储桶中各个文件的访问。

无论使用哪种方法,您仍应查看权限,从而确保:

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

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

重要

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

请注意以下几点:

  • 您可能发现使用 Amazon S3 存储桶策略比对象 ACL 更容易,因为您可将文件添加到存储桶而无需更新权限。但是,通过 ACL 可以进行更高精度的控制,因为您可授予每个单独文件的权限。

  • 默认情况下,您的 Amazon S3 存储桶及其中包含的所有文件都是私有的。只有创建该存储桶的AWS账户有权读取或写入文件。

  • 如果另一个AWS账户将文件上传到您的存储桶,则该账户是这些文件的所有者。存储桶策略仅适用于存储桶拥有者所拥有的文件。这意味着,如果另一个账户将文件上传到您的存储桶,则不会针对这些文件评估您为 OAI 创建的存储桶策略。在这种情况下,使用对象 ACL 向您的 OAI 授予权限。

  • 如果您将 OAI 添加到现有分配中,则视情况修改存储桶策略或任何对象 ACL,以确保文件在 CloudFront 外部不是公开可用的。

  • 授予一个或多个安全管理员账户额外的权限,以便您可继续更新 Amazon S3 存储桶的内容。

重要

在保存对 Amazon S3 权限的更改和更改生效之间可能有短暂的延迟。在更改生效之前,尝试访问存储桶中的文件时可能会得到“权限被拒绝”错误。

使用 Amazon S3 存储桶策略

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

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

  • 使用 Amazon S3 API 中的 PutBucketPolicy

  • 使用 CloudFront 控制台。在 CloudFront 控制台中向源设置添加 OAI 时,您可以选择是,更新存储桶策略,以便让 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

您还可以使用其 Amazon S3 规范 ID 将 OAI 指定为 Principal。例如:

"Principal": { "CanonicalUser": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be" }

在使用上述示例时,请将 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be 替换为 OAI 的规范 ID。您可以通过查找 OAI ID 的相同方式来查找其规范 ID。

注意

使用 OAI 的 ARN 将其指定为 Principal 的一个优点是,更容易了解存储桶策略向谁授予访问权限。Amazon S3 规范 ID 可以引用不同类型的AWS 身份,而不仅仅是 CloudFront OAI,而且很难确定规范 ID 所指的身份。使用 OAI 的 ARN 时,您可以更轻松地理解存储桶策略。

此外,在存储桶策略中使用 OAI 的规范 ID 时,AWS会将规范 ID 替换为该 OAI 的 ARN。如果您编写指定 OAI 的规范 ID 的策略,并稍后再查看相同策略,您将看到该规范 ID 已由相应的 ARN 替换。因此,使用 OAI 的 ARN 来编写策略可能会更有意义。

向 OAI 授予权限

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

Amazon S3 存储桶策略示例

以下示例显示了向 CloudFront OAI 授予访问权限的 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

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

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

有关 Amazon S3 权限的更多信息,请参阅《Amazon Simple Storage Service 开发人员指南》中的使用 ACL 管理访问权限

在仅支持签名版本 4 身份验证的 Amazon S3 区域中使用 OAI

较新的 Amazon S3 区域要求对通过身份验证的请求使用签名版本 4。(有关每个 Amazon S3 区域支持的签名版本,请参阅 Amazon Web Services 一般参考中的区域和终端节点主题中的 Amazon Simple Storage Service (S3)。) 不过,如果您创建源访问身份并将其添加到 CloudFront 分配中,在请求您的 Amazon S3 存储桶中的文件时,CloudFront 通常使用签名版本 4 来进行身份验证。如果使用源访问身份并且存储桶位于要求使用签名版本 4 进行身份验证的区域之一,请注意以下几点:

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

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

  • 不支持 POST 请求。