Amazon S3 条件键 - Amazon Simple Storage Service

Amazon S3 条件键

访问策略语言使您可以在授予权限时指定条件。要指定策略生效时的条件,您可以使用可选 Condition 元素或 Condition 块来指定策略生效时的条件。您可以使用预定义的 AWS 范围内的键和特定于 Amazon S3 的键来指定 Amazon S3 访问策略中的条件。

Condition 元素中,您可构建表达式并使用布尔运算符(等于、小于等)将条件与请求中的值进行匹配。例如,当授予用户上传对象的权限时,存储桶拥有者可通过添加 StringEquals 条件要求此对象可公开读取,如下所示:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Action": "s3:PutObject", "Resource": [ "arn:aws:s3:::awsexamplebucket1/*" ], "Condition": { "StringEquals": { "s3:x-amz-acl": "public-read" } } } ] }

在本例中,Condition 块指定应用于指定的键值对 "s3:x-amz-acl":["public-read"]StringEquals 条件。有一组预定义键可用于表达条件。此示例使用 s3:x-amz-acl 条件键。此条件要求用户包含 x-amz-acl 标头,并且值 public-read 位于每个 PUT 对象请求中。

AWS 范围的条件键

AWS 提供一组常用键,所有支持策略的 AWS 服务均支持这些键。这些键称为 AWS 范围的键并使用前缀 aws:。有关 AWS 范围的条件键的完整列表,请参阅《IAM 用户指南》中的可用的 AWS 条件键

您可以在 Amazon S3 中使用 AWS 范围的条件键。如果请求源自特定 IP 地址范围 (192.0.2.0.*),则以下示例存储桶策略可使已经过身份验证的用户具有使用 s3:GetObject 操作的权限,除非此 IP 地址为 192.0.2.188。在条件块中,IpAddressNotIpAddress 为条件,每个条件均提供了一个键值对用于评估。此示例中的两个键-值对均使用 aws:SourceIp AWS 范围内的键。

注意

请注意,在条件中指定的 IPAddressNotIpAddress 键值使用 RFC 4632 中描述的 CIDR 表示法。有关详细信息,请参阅 http://www.rfc-editor.org/rfc/rfc4632.txt

{ "Version": "2012-10-17", "Id": "S3PolicyId1", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": "*", "Action":"s3:GetObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition" : { "IpAddress" : { "aws:SourceIp": "192.0.2.0/24" }, "NotIpAddress" : { "aws:SourceIp": "192.0.2.188/32" } } } ] }

您还可以在 Amazon S3 策略中使用其他 AWS 范围的条件键。例如,您可以在适用于 VPC 终端节点的存储桶策略中指定 aws:SourceVpceaws:SourceVpc 条件键。有关示例,请参阅 Amazon S3 的 VPC 终端节点的示例存储桶策略

特定于 Amazon S3 的条件键

您可以将 Amazon S3 条件键与特定的 Amazon S3 操作一起使用。每个条件键均映射到可设置条件的 API 所允许的相同名称请求标头。特定于 Amazon S3 的条件键指定同名请求标头的行为。有关特定于 Amazon S3 的条件键的完整列表,请参阅Amazon S3 的操作、资源和条件键

例如,条件键 s3:x-amz-acl 可用于对 s3:PutObject 权限授予条件权限,它定义 PUT 对象 API 支持的 x-amz-acl 请求标头的行为。条件键 s3:VersionId 可用于对 s3:GetObjectVersion 权限授予条件权限,它定义您在 GET Object 请求中设置的查询参数 versionId 的行为。

如果请求包含可使对象公开可读的 x-amz-acl 标头,则以下存储桶策略为两个 AWS 账户授予 s3:PutObject 权限。Condition 块使用 StringEquals 条件,并且提供键值对 "s3:x-amz-acl":["public-read",以进行评估。在该键值对中,s3:x-amz-acl 是特定于 Amazon S3 的键,如前缀 s3: 所示。

{ "Version":"2012-10-17", "Statement": [ { "Sid":"AddCannedAcl", "Effect":"Allow", "Principal": { "AWS": [ "arn:aws:iam::Account1-ID:root", "arn:aws:iam::Account2-ID:root" ] }, "Action":"s3:PutObject", "Resource": ["arn:aws:s3:::awsexamplebucket1/*"], "Condition": { "StringEquals": { "s3:x-amz-acl":["public-read"] } } } ] }
重要

并非所有条件对所有操作都有意义。例如,在授予 s3:CreateBucket Amazon S3 权限的策略上包含 s3:LocationConstraint 条件是有意义的。但是,在授予 s3:GetObject 权限的策略中包含此条件没有意义。Amazon S3 可测试是否存在此类涉及 Amazon S3 特定条件的语义错误。但如果要创建针对 IAM 用户的策略,并且包含了语义无效的 Amazon S3 条件,则不报告错误,因为 IAM 无法验证 Amazon S3 条件。

示例 — 针对对象操作的 Amazon S3 条件键

本节提供示例,说明如何将特定于 Amazon S3 的条件键用于对象操作。有关可以在策略中指定的 Amazon S3 操作、条件键和资源的完整列表,请参阅Amazon S3 的操作、资源和条件键

几个示例策略展示如何将条件键与 PUT Object 操作结合使用。PUT Object 操作允许特定于访问控制列表 (ACL) 的标头,可用于授予基于 ACL 的权限。通过使用这些键,存储桶拥有者可设置条件,要求用户上传对象时需具有特定访问权限。您还可以通过 PutObjectAcl 操作授予基于 ACL 的权限。有关更多信息,请参阅《Amazon S3 Amazon Simple Storage Service API 参考》中的 PutObjectAcl。有关 ACL 的更多信息,请参阅 访问控制列表 (ACL) 概述

示例 1:授予 s3:PutObject 权限,并指定一个条件以要求存储桶拥有者获得完全控制权

PUT Object 操作允许特定于访问控制列表 (ACL) 的标头,可用于授予基于 ACL 的权限。通过使用这些键,存储桶拥有者可设置条件,要求用户上传对象时需具有特定访问权限。

假设账户 A 拥有一个存储桶,而账户管理员想要授予账户 B 中的用户 Dave 上传对象的权限。默认情况下,Dave 上传的对象由账户 B 拥有,而账户 A 对这些对象没有权限。由于存储桶拥有者要支付账单,需要对 Dave 上传的对象具有全部权限。要实现这一目的,账户 A 管理员可向 Dave 授予 s3:PutObject 权限,指定的条件要求请求包含 ACL 特定标头(用于显式授予全部权限)或使用标准 ACL。有关更多信息,请参阅 PUT Object

需要 x-amz-full-control 标头

您可以要求在请求中具有 x-amz-full-control 标头,授予存储桶拥有者完全控制权限。以下存储桶策略向用户 Dave 授予 s3:PutObject 权限,使用 s3:x-amz-grant-full-control 条件键指定了条件,要求此请求包含 x-amz-full-control 标头。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AccountB-ID:user/Dave" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition": { "StringEquals": { "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID" } } } ] }
注意

此示例是关于跨账户权限的。不过,如果 Dave(正在获得权限)属于拥有存储桶的 AWS 账户,则该条件权限不是必需的。这是因为,Dave 所属的父账户拥有用户上传的对象。

添加显式拒绝

上述存储桶策略向账户 B 中的用户 Dave 授予条件权限。当该策略生效时,Dave 可通过其他某个策略获得没有任何条件的相同权限。例如,Dave 可能属于一个组,并且您为该组授予 s3:PutObject 权限而没有指定任何条件。为避免这些权限漏洞,可通过添加显式拒绝编写更严格的访问策略。在该示例中,如果用户 Dave 的请求没有包含必要标头向存储桶拥有者授予全部权限,则您显式拒绝他的上传权限。显式拒绝始终取代授予的其他任何权限。以下是添加了显式拒绝的经修订的访问策略示例。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AccountB-ID:user/AccountBadmin" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition": { "StringEquals": { "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID" } } }, { "Sid": "statement2", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::AccountB-ID:user/AccountBadmin" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition": { "StringNotEquals": { "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID" } } } ] }

使用 AWS CLI 测试策略

如果您有两个 AWS 账户,则可以使用 AWS 命令行界面 (AWS CLI) 测试策略。您可以附加此策略,并使用 Dave 的凭证通过以下 AWS CLI put-object 命令测试权限。通过添加 --profile参数提供 Dave 的凭证。通过添加 --grant-full-control 参数可向存储桶拥有者授予完全控制权限。有关设置和使用 AWS CLI 的更多信息,请参阅 设置用于示例演练的工具

aws s3api put-object --bucket examplebucket --key HappyFace.jpg --body c:\HappyFace.jpg --grant-full-control id="AccountA-CanonicalUserID" --profile AccountBUserProfile

需要 x-amz-acl 标头

您可以要求 x-amz-acl 标头,带有向存储桶拥有者授予完全控制权限的标准 ACL。如果要求在请求中使用 x-amz-acl 标头,您可以替换 Condition 块中的键值对并指定 s3:x-amz-acl 条件键,如以下示例中所示。

"Condition": { "StringNotEquals": { "s3:x-amz-acl": "bucket-owner-full-control" }

要使用 AWS CLI 测试权限,则指定 --acl 参数。然后 AWS CLI 在其发送此请求时添加 x-amz-acl 标头。

aws s3api put-object --bucket examplebucket --key HappyFace.jpg --body c:\HappyFace.jpg --acl "bucket-owner-full-control" --profile AccountBadmin

示例 2:授予 s3:PutObject 权限,以要求使用服务器端加密存储对象

假设账户 A 拥有一个存储桶。账户管理员想要授予账户 A 中的用户 Jane 上传对象的权限,条件是 Jane 始终请求服务器端加密,使 Amazon S3 保存加密的对象。账户 A 管理员可使用所示的 s3:x-amz-server-side-encryption 条件键来完成。Condition 块中的键值对指定 s3:x-amz-server-side-encryption 键。

"Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" }

当使用 AWS CLI 测试此权限时,必须使用 --server-side-encryption 参数添加所需的参数。

aws s3api put-object --bucket example1bucket --key HappyFace.jpg --body c:\HappyFace.jpg --server-side-encryption "AES256" --profile AccountBadmin

示例 3:授予 s3:PutObject 权限以复制具有复制源限制的对象

在 PUT 对象请求中,如果指定了源对象,则为一个复制操作(请参阅 PUT 对象 - 复制)。因此,存储桶拥有者可以为用户授予权限以复制具有源限制的对象,例如:

  • 允许仅从 sourcebucket 存储桶复制对象。

  • 允许从源存储桶复制对象,并仅复制键名称前缀开头为 public/ 的对象(例如 sourcebucket/public/*)。

  • 仅允许从源存储桶复制特定对象(例如,sourcebucket/example.jpg)。

以下存储桶策略为用户 (Dave) 授予 s3:PutObject 权限。该权限允许用户仅复制满足以下条件的对象:请求包含 s3:x-amz-copy-source 标头,并且标头值指定 /awsexamplebucket1/public/* 键名称前缀。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "cross-account permission to user in your own account", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/Dave" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*" }, { "Sid": "Deny your user permission to upload object if copy source is not /bucket/folder", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::123456789012:user/Dave" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition": { "StringNotLike": { "s3:x-amz-copy-source": "awsexamplebucket1/public/*" } } } ] }

使用 AWS CLI 测试策略

可使用 AWS CLI copy-object 命令测试此权限。可通过添加 --copy-source 参数指定源;键名称前缀必须与策略中允许的前缀相匹配。您需要使用 --profile 参数为用户 Dave 提供凭证。有关设置 AWS CLI 的更多信息,请参阅设置用于示例演练的工具

aws s3api copy-object --bucket awsexamplebucket1 --key HappyFace.jpg --copy-source examplebucket/public/PublicHappyFace1.jpg --profile AccountADave

授予仅复制特定对象的权限

上述策略使用 StringNotLike 条件。要授予仅复制特定对象的权限,您必须将条件从 StringNotLike 更改为 StringNotEquals,然后指定所示的对象键。

"Condition": { "StringNotEquals": { "s3:x-amz-copy-source": "awsexamplebucket1/public/PublicHappyFace1.jpg" } }

示例 4:授予特定对象版本的访问权限

假设账户 A 拥有启用版本控制的存储桶。该存储桶具有 HappyFace.jpg 对象的多个版本。账户管理员现在想要授予用户 Dave 仅获得特定对象版本的权限。账户管理员可通过有条件地授予 Dave 下面所示的 s3:GetObjectVersion 权限来实现这一点。Condition 块中的键值对指定 s3:VersionId 条件键。在这种情况下,Dave 需要知道确切的对象版本 ID 才能检索该对象。

有关更多信息,请参阅《Amazon Simple Storage Service API 参考》中的 GetObject

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/Dave" }, "Action": "s3:GetObjectVersion", "Resource": "arn:aws:s3:::examplebucketversionenabled/HappyFace.jpg" }, { "Sid": "statement2", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::123456789012:user/Dave" }, "Action": "s3:GetObjectVersion", "Resource": "arn:aws:s3:::examplebucketversionenabled/HappyFace.jpg", "Condition": { "StringNotEquals": { "s3:VersionId": "AaaHbAQitwiL_h47_44lRO2DDfLlBO5e" } } } ] }

使用 AWS CLI 测试策略

可使用 AWS CLI get-object 命令以及标识特定对象版本的 --version-id参数来测试这些权限。此命令会检索该对象,并将其保存到 OutputFile.jpg 文件。

aws s3api get-object --bucket examplebucketversionenabled --key HappyFace.jpg OutputFile.jpg --version-id AaaHbAQitwiL_h47_44lRO2DDfLlBO5e --profile AccountADave

示例 5:将对象上传限制为具有特定存储类的对象

假设账户 A(由账户 ID 123456789012 表示)拥有一个存储桶。账户管理员想要限制 Dave (账户 A 中的一名用户) 只能将使用 STANDARD_IA 存储类存储的对象上传到此存储桶。要将对象上传限制到特定的存储类,账户 A 管理员可以使用 s3:x-amz-storage-class 条件键,如以下示例存储桶策略所示。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/Dave" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::awsexamplebucket1/*", "Condition": { "StringEquals": { "s3:x-amz-storage-class": [ "STANDARD_IA" ] } } } ] }

示例 6:基于对象标签授予权限

有关如何将对象标签条件键与 Amazon S3 操作结合使用的示例,请参阅对象标签和访问控制策略

示例 — 针对存储桶操作的 Amazon S3 条件键

本节提供示例策略,说明如何将特定于 Amazon S3 的条件键用于存储桶操作。

示例 1:授予用户仅在特定区域中创建存储桶的权限

假定 AWS 账户管理员想要授予其用户 (Dave) 仅在南美洲(圣保罗)区域创建存储桶的权限。账户管理员可附加以下用户策略,授予附带条件的 s3:CreateBucket 权限,如下所示。Condition 块中的键值对指定 s3:LocationConstraint 键,并将 sa-east-1 区域作为值。

注意

在该示例中,存储桶拥有者为其用户之一授予权限,因此可以使用存储桶策略或用户策略。此示例显示了用户策略。

有关 Amazon S3 区域的列表,请参阅《AWS 一般参考》中的区域和终端节点

{ "Version":"2012-10-17", "Statement":[ { "Sid":"statement1", "Effect":"Allow", "Action": "s3:CreateBucket", "Resource": "arn:aws:s3:::*", "Condition": { "StringLike": { "s3:LocationConstraint": "sa-east-1" } } } ] }

添加显式拒绝

前面的策略限制用户只能在 sa-east-1 区域中创建存储桶。但是,别的策略可能授予此用户在其他区域中创建存储桶的权限。例如,如果用户属于某个组,该组可能附加了一个策略,以允许该组中的所有用户在另一个区域中创建存储桶。要确保此用户不会获得在其他任何区域创建存储桶的权限,可在上述策略中添加一个显式拒绝语句。

Deny 语句使用 StringNotLike 条件。也即,如果位置约束不是 sa-east-1,则创建存储桶的请求将被拒绝。显式拒绝不允许用户在其他任何区域创建存储桶,无论该用户获得了哪种其他权限。以下策略包含显式拒绝语句。

{ "Version":"2012-10-17", "Statement":[ { "Sid":"statement1", "Effect":"Allow", "Action": "s3:CreateBucket", "Resource": "arn:aws:s3:::*", "Condition": { "StringLike": { "s3:LocationConstraint": "sa-east-1" } } }, { "Sid":"statement2", "Effect":"Deny", "Action": "s3:CreateBucket", "Resource": "arn:aws:s3:::*", "Condition": { "StringNotLike": { "s3:LocationConstraint": "sa-east-1" } } } ] }

使用 AWS CLI 测试策略

可使用以下 create-bucket AWS CLI 命令测试此策略。此示例使用 bucketconfig.txt 文件来指定位置约束。记下此 Windows 文件路径。您需要更新相应的存储桶名称和路径。必须使用 --profile 参数提供用户凭证。有关设置和使用 AWS CLI 的更多信息,请参阅 设置用于示例演练的工具

aws s3api create-bucket --bucket examplebucket --profile AccountADave --create-bucket-configuration file://c:/Users/someUser/bucketconfig.txt

bucketconfig.txt 文件指定一些配置,如下所示。

{"LocationConstraint": "sa-east-1"}

示例 2:获取存储桶中具有特定前缀的对象列表

您可以使用 s3:prefix 条件键将 GET Bucket (ListObjects) API 的响应限制为具有特定前缀的键名。如果您是存储桶拥有者,您可限定用户仅列出存储桶中特定前缀的内容。如果存储桶中的对象按键名前缀组织,此条件键非常有用。Amazon S3 控制台使用键名前缀来显示文件夹概念。只有控制台支持文件夹的概念;Amazon S3 API 仅支持存储桶和对象。有关使用前缀和分隔符筛选访问权限的更多信息,请参阅演练:使用用户策略控制对存储桶的访问

例如,如果您有键名为 public/object1.jpgpublic/object2.jpg 的两个对象,则该控制台会在 public 文件夹下显示这些对象。在 Amazon S3 API 中,这些是带有前缀的对象,而不是文件夹中的对象。但是,在 Amazon S3 API 中,如果使用这些前缀组织对象键,则可授予 s3:ListBucket 权限,s3:prefix 条件为允许用户获得具有这些特定前缀的键名的列表。

在该示例中,存储桶拥有者和用户所属的父账户相同。因此存储桶拥有者可使用存储桶策略或用户策略。有关可与 GET Bucket (ListObjects) API 一起使用的其他条件键的更多信息,请参阅 ListObjects

用户策略

以下用户策略授予 s3:ListBucket 权限(请参阅 GET Bucket (List Objects)),条件为要求用户在请求中指定值为 projectsprefix

{ "Version":"2012-10-17", "Statement":[ { "Sid":"statement1", "Effect":"Allow", "Action": "s3:ListBucket", "Resource":"arn:aws:s3:::awsexamplebucket1", "Condition" : { "StringEquals" : { "s3:prefix": "projects" } } }, { "Sid":"statement2", "Effect":"Deny", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::awsexamplebucket1", "Condition" : { "StringNotEquals" : { "s3:prefix": "projects" } } } ] }

此条件将用户限定于列出具有 projects 前缀的对象键。添加的显式拒绝将拒绝用户列出具有其他任何前缀的键,无论该用户可能具有其他什么权限。例如,通过更新先前用户策略或通过存储桶策略,该用户有可能获得列出没有任何限制的对象键的权限。由于显式拒绝始终优先于其他任何权限,因此列出非 projects 前缀的键的用户请求会被拒绝。

存储桶策略

如果将 Principal 元素添加到上述的用户策略,标识用户,则现在您拥有了所示的存储桶策略。

{ "Version":"2012-10-17", "Statement":[ { "Sid":"statement1", "Effect":"Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/bucket-owner" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::awsexamplebucket1", "Condition" : { "StringEquals" : { "s3:prefix": "projects" } } }, { "Sid":"statement2", "Effect":"Deny", "Principal": { "AWS": "arn:aws:iam::123456789012:user/bucket-owner" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::awsexamplebucket1", "Condition" : { "StringNotEquals" : { "s3:prefix": "examplefolder" } } } ] }

使用 AWS CLI 测试策略

可使用以下 list-object AWS CLI 命令测试此策略。在该命令中,使用 --profile 参数提供用户凭证。有关设置和使用 AWS CLI 的更多信息,请参阅 设置用于示例演练的工具

aws s3api list-objects --bucket awsexamplebucket1 --prefix examplefolder --profile AccountADave

如果该存储桶启用了版本控制,要列出该存储桶中的对象,必须在上述策略中授予 s3:ListBucketVersions 权限,而不是 s3:ListBucket 权限。此权限还支持 s3:prefix 条件键。

示例 3:设置最大键数

您可以使用 s3:max-keys 条件键设置请求者在 GET Bucket (ListObjects)ListObjectVersions 请求中可以返回的最大键数。默认情况下,API 返回最多 1000 个键。有关可与 s3:max-keys 一起使用的数字条件运算符的列表和相关示例,请参阅《IAM 用户指南》中的数字条件运算符