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:::examplebucket/*" ], "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:::examplebucket/*", "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:::examplebucket/*"], "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 对象操作结合使用。PUT 对象操作允许在授予基于 ACL 的权限时可使用的访问控制列表 (ACL) 特定的标头。通过使用这些键,存储桶拥有者可设置条件,要求用户上传对象时需具有特定访问权限。您还可以通过 PutObjectAcl 操作授予基于 ACL 的权限。有关详细信息,请参阅 Amazon S3 Amazon Simple Storage Service API Reference 中的 PutObjectacl 。有关 ACL 的更多信息,请参阅 访问控制列表 (ACL) 概述

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

PUT 对象操作允许在授予基于 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:::examplebucket/*", "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:::examplebucket/*", "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:::examplebucket/*", "Condition": { "StringNotEquals": { "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID" } } } ] }

使用 AWS CLI 测试策略

如果您有两个 AWS 账户,则可使用 AWS Command Line Interface (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 存储桶复制对象。

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

  • 只允许从 sourcebucket 复制特定对象(例如 sourcebucket/example.jpg)。

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

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

使用 AWS CLI 测试策略

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

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

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

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

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

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

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

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

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AccountA-ID:user/Dave" }, "Action": ["s3:GetObjectVersion"], "Resource": "arn:aws:s3:::examplebucketversionenabled/HappyFace.jpg" }, { "Sid": "statement2", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::AccountA-ID: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 拥有一个存储桶。账户管理员想要限制 Dave (账户 A 中的一名用户) 只能将使用 STANDARD_IA 存储类存储的对象上传到此存储桶。要将对象上传限制到特定的存储类,账户 A 管理员可以使用 s3:x-amz-storage-class 条件键,如以下示例存储桶策略所示。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AccountA-ID:user/Dave" }, "Action": "s3:PutObject", "Resource": [ "arn:aws:s3:::examplebucket/*" ], "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 General Reference 中的区域和终端节点

{ "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(列出对象)),条件为要求用户在请求中指定值为 projectsprefix

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

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

存储桶策略

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

{ "Version":"2012-10-17", "Statement":[ { "Sid":"statement1", "Effect":"Allow", "Principal": { "AWS": "arn:aws:iam::BucketOwner-accountID:user/user-name" }, "Action":[ "s3:ListBucket" ], "Resource":[ "arn:aws:s3:::examplebucket" ], "Condition" : { "StringEquals" : { "s3:prefix": "examplefolder" } } }, { "Sid":"statement2", "Effect":"Deny", "Principal": { "AWS": "arn:aws:iam::BucketOwner-AccountID:user/user-name" }, "Action":[ "s3:ListBucket" ], "Resource":[ "arn:aws:s3:::examplebucket" ], "Condition" : { "StringNotEquals" : { "s3:prefix": "examplefolder" } } } ] }

使用 AWS CLI 测试策略

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

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

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

示例 3:设置最大键数

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