AWS Identity and Access Management
用户指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

创建具有多个键或值的条件

您可以使用策略的 Condition 元素测试请求中的多个键或单个键的多个值。在以编程方式或通过 AWS 管理控制台向 AWS 发出请求时,请求包含有关您的委托人、操作和标签等的信息。要了解请求中包含的信息和数据,请参阅请求。您可以使用条件键来测试请求中的匹配键的值。例如,您可以使用条件键根据标签控制对 DynamoDB 表的特定属性或 Amazon EC2 实例的访问。

一个 Condition 元素可以包含多个条件,而每个条件又可以包含多个键值对。大多数条件键支持使用多个值。下图对此进行了说明。除非另行指定,否则所有键均可有多个值。

具有多个键或值的条件的评估逻辑

如果您的策略具有多个条件运算符或将多个键附加到单个条件运算符,则使用逻辑 AND 评估条件。如果单个条件运算符包含一个键的多个值,则采用逻辑 OR 评估该条件运算符。必须满足所有条件运算符才能做出允许或显式拒绝决定。如果任一条件运算符没有满足,那么结果为拒绝。


            条件块显示了如何将 AND 和 OR 应用于多个值

使用多个键和值

对于包含单个键的多个值的请求,必须将条件括在方括号内,例如数组 ("Key2":["Value2A", "Value2B"])。您还必须在 StringLike 条件运算符中使用 ForAllValuesForAnyValue 集合运算符。这些限定词为条件运算符添加了集合运算功能,以便您针对多个条件值测试多个请求值。

  • ForAllValues – 测试整个请求值集合是否与整个条件键值集合匹配。如果请求中的所有指定的键值与策略中的至少一个值匹配,则条件返回 true。如果请求中没有匹配的键或者键值解析为空数据集(如空字符串),也会返回 true。

  • ForAnyValue – 测试请求值集合的至少一个数字是否与条件键值集合的至少一个成员匹配。如果请求中的任何一个键值与策略中的任何一个条件值匹配,则条件返回 true。对于没有匹配的键或空数据集,条件返回 false。

假设您希望仅在一个数值 foo 等于 A 或 B 并且另一个数值 bar 等于 C 时,才让 John 使用资源。应创建如下图所示的条件块。


         包含两个 NumericEquals 条件的条件块

假设您还希望将 John 的访问限制为 2019 年 1 月 1 日之后。应添加另一条件 DateGreaterThan,并且日期等于 2019 年 1 月 1 日。这时,条件块将与下图类似。


         条件块包含 DateGreaterThan 条件

AWS 具有预定义的条件运算符和键(如 aws:CurrentTime)。各个 AWS 服务还会定义服务特定的键。

例如,假设您希望让用户 John 在以下情况下访问 Amazon SQS 队列:

  • 时间为 2019 年 7 月 16 日中午 12:00 之后

  • 时间为 2019 年 7 月 16 日下午 3:00 之前

  • 请求来自 192.0.2.0 到 192.0.2.255 203.0.113.0 到 203.0.113.255 范围内的 IP 地址。

在您的条件块中包含三个独立的条件运算符,而 John 必须满足所有三个条件运算符才能访问您的队列、主题或资源。

条件块在你们策略中的样子如下所示。将使用 OR 评估 aws:SourceIp 的两个值,并使用 AND 评估三个单独的条件运算符。

"Condition" : { "DateGreaterThan" : { "aws:CurrentTime" : "2019-07-16T12:00:00Z" }, "DateLessThan": { "aws:CurrentTime" : "2019-07-16T15:00:00Z" }, "IpAddress" : { "aws:SourceIp" : ["192.0.2.0/24", "203.0.113.0/24"] } }

将多个值与条件集合运算符一起使用的示例

您可以创建一个策略,以根据您在策略中指定的一个或多个值测试请求中的多个值。假设有一个名为 Thread 的 Amazon DynamoDB 表用来存储某技术支持论坛中有关话题的信息。该表具有名为 IDUserNamePostDateTimeMessageTags 的属性。

{ ID=101 UserName=Bob PostDateTime=20130930T231548Z Message="A good resource for this question is docs.aws.amazon.com" Tags=["AWS", "Database", "Security"] }

有关如何在 DynamoDB 中使用集合运算符以实施对单个数据项和属性的精细访问的信息,请参阅 Amazon DynamoDB 开发人员指南 中的 DynamoDB 精细访问控制

您可以创建一个策略以允许用户仅查看 PostDateTimeMessageTags 属性。如果用户的请求包含其中的任何属性,则允许该请求。但如果请求包含任何其他属性(例如 ID),则拒绝该请求。从逻辑上讲,您希望创建允许的属性列表 (PostDateTime, Message, Tags)。您还希望在策略中指示,用户请求的所有属性必须位于该允许的属性列表中。

以下示例策略显示如何将 ForAllValues 限定词与 StringEquals 条件运算符搭配使用。该条件 允许用户请求名为 Thread 的 DynamoDB 表中的 IDMessageTags 属性。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "dynamodb:GetItem", "Resource": "arn:aws:dynamodb:*:*:table/Thread", "Condition": { "ForAllValues:StringEquals": { "dynamodb:Attributes": [ "ID", "Message", "Tags" ] } } } ] }

假设用户向 DynamoDB 发出请求以从 Thread 表中获取 MessageTags 属性。在这种情况下,允许该请求,因为用户请求的属性均与策略中指定的值匹配。GetItem 操作要求用户将 ID 属性作为数据库表键传递(策略也允许这样做)。不过,如果用户的请求包含 UserName 属性,请求将会失败。原因是 UserName 不在允许的属性列表中,并且 ForAllValues 限定词要求所有请求的值在策略中列出。

重要

如果使用 dynamodb:Attributes,您必须指定表的所有主键和索引键属性的名称。您还必须指定在策略中列出的任何二级索引。否则,DynamoDB 无法使用这些键属性执行所请求的操作。

或者,您可能希望确保明确禁止用户在请求中包含某些属性,如 IDUserName 属性。例如,您可能会在用户更新 DynamoDB 表时排除一些属性,因为更新(PUT 操作)不应更改特定属性。在这种情况下,您创建禁止的属性列表 (ID, UserName)。如果用户请求的任何属性与任何禁止的属性匹配,则拒绝该请求。

以下示例说明如何使用 ForAnyValue 限定词以在用户尝试执行 ID 操作时拒绝对 PostDateTimePutItem 属性的访问。也就是说,在用户尝试更新 Thread 表中的任一属性的情况下。请注意,Effect 元素设置为 Deny

{ "Version": "2012-10-17", "Statement": { "Effect": "Deny", "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:*:*:table/Thread", "Condition": { "ForAnyValue:StringEquals": { "dynamodb:Attributes": [ "ID", "PostDateTime" ] } } } }

假定用户请求更新 PostDateTime 表的 MessageThread 属性。ForAnyValue 限定词可确定是否有请求的属性在策略列表中出现。在这种情况下,只有一项匹配 (PostDateTime),因此,条件为 true。假设请求中的其他值也可以满足 (例如,资源),则总策略评估返回 true。因为策略的效果为 Deny,请求被拒绝。

假设用户改为只请求对 PutItem 属性执行 UserName。请求中没有任何属性 (仅 UserName) 与策略中列出的任何属性 (IDPostDateTime) 相匹配。条件将返回 false,因此,策略 (Deny) 的效果也为 false,该策略不会拒绝该请求。(为使请求取得成功,必须由不同的策略显式允许它。此策略没有显式拒绝它,但所有请求都被隐式拒绝。)

将多个值与条件集合运算符一起使用的评估逻辑

本部分讨论有关与 ForAllValuesForAnyValue 限定词结合使用的评估逻辑的详细信息。下表显示请求中可能包含的键 (PostDateTimeUserName),以及一个包含 PostDateTimeMessageTags 值的策略条件。

键(在请求中)

条件值(在策略中)

PostDateTime

PostDateTime

UserName

Message

 

Tags

组合的评估如下:

PostDateTime matches PostDateTime?

PostDateTime matches Message?

PostDateTime matches Tags?

UserName matches PostDateTime?

UserName matches Message?

UserName matches Tags?

条件运算符结果取决于策略条件使用了哪个修饰符:

  • ForAllValues。如果请求中的每个键 (PostDateTimeUserName) 至少与策略中的一个条件值 (PostDateTimeMessageTags) 匹配,则条件运算符将返回 true。换言之,为了使条件返回 true,PostDateTime 必须等于 PostDateTimeMessageTags 并且 UserName 必须等于 PostDateTimeMessageTags

  • ForAnyValue。如果请求值和策略值的任意组合 (示例中的六种组合之一) 返回 true,则条件运算符将返回 true。

以下策略包含一个 ForAllValues 限定词:

{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "dynamodb:GetItem", "Resource": "arn:aws:dynamodb:*:*:table/Thread", "Condition": { "ForAllValues:StringEquals": { "dynamodb:Attributes": [ "PostDateTime", "Message", "Tags" ] } } } }

假设用户向 DynamoDB 请求获取 PostDateTimeUserName 属性。组合的评估如下:

PostDateTime matches PostDateTime?

True

PostDateTime matches Message?

False

PostDateTime matches Tags?

False

UserName matches PostDateTime?

False

UserName matches Message?

False

UserName matches Tags?

False

策略包含 ForAllValues 条件运算符修饰符,这意味着 PostDateTimeUserName 必须至少各有一个匹配项。UserName 没有匹配项,因此条件运算符将返回 false,且策略将拒绝请求。

以下策略包含一个 ForAnyValue 限定词:

{ "Version": "2012-10-17", "Statement": { "Effect": "Deny", "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:*:*:table/Thread", "Condition": { "ForAnyValue:StringEquals": { "dynamodb:Attributes": [ "ID", "PostDateTime" ] } } } }

请注意,策略包含 "Effect":"Deny",操作是 PutItem。假设用户的 PutItem 请求包含属性 UserNameMessagePostDateTime。评估如下:

UserName matches ID?

False

UserName matches PostDateTime?

False

Messages matches ID?

False

Message matches PostDateTime?

False

PostDateTime matches ID?

False

PostDateTime matches PostDateTime?

True

使用修饰符 ForAnyValue 后,如果任何一个测试返回 true,则条件将返回 true。最后一个测试返回 true,因此条件也将返回 true;因为 Effect 元素设置为 Deny,因此请求将被拒绝。

注意

如果请求中的键值解析为空数据集(例如,空字符串),ForAllValues 修饰的条件运算符将返回 true。此外,ForAnyValue 修饰的条件运算符返回 false。