创建具有多个键或值的条件 - Amazon Identity and Access Management
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

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

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

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

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

如果您的策略具有多个条件运算符或将多个键附加到单个条件运算符,则使用逻辑 AND 评估条件。如果单个条件运算符包含一个键的多个值,则采用逻辑 OR 评估该条件运算符。要触发所需的 AllowDeny 效果,所有条件都必须解析为 true。


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

当多个值针对否定匹配条件运算符(StringNotEqualsDateNotEquals)在策略中列出时,有效权限会像 AND 那样工作。例如,如果在 StringNotEquals 条件运算符中有多个 aws:PrincipalAccount 值,则字符串无法匹配用来将条件转换为 true 所罗列的 aws:PrincipalAccount 数值。

使用多个键和值

要将条件与具有多个键值的请求上下文进行比较,必须使用 ForAllValues 或者 ForAnyValue 集合运算符。这些集合运算符用于比较两组值。

当策略条件比较两组值(例如请求中的标签集和策略条件中的标签集)时,您需要告诉 Amazon 如何比较集合。IAM 定义了两个集合运算符,ForAnyValueForAllValues。您必须将集合运算符用于多值条件键。不要将集合运算符用于单值条件键

要确定 Amazon 条件键为单值还是多值,请查看其数据类型。要查看用于一项服务的条件键数据类型,请参阅Amazon 服务的操作、资源和条件键,然后选择要查看其条件键的服务。如果条件 Type(类型)字段包含 ArrayOf 前缀,则条件键为多值。例如,Amazon Key Management Service 支持 String 单值数据类型和 ArrayOfString 多值数据类型的条件键。

  • 单值条件键在请求上下文中最多有一个值。例如,您可以在 Amazon 中标记资源。资源标签存储为标签键值对。资源标签键可以具有单个标签值。因此,aws:ResourceTag/tag-key 是一个单值条件键。不要将集合运算符用于单值条件键。

  • 多值条件键在请求上下文中可以有多个值。例如,您可以在 Amazon 中标记资源并在请求中包含多个标签键值对。因此,aws:TagKeys 是一个多值条件键。多值条件键需要一个集合运算符。

限定词 ForAllValuesForAnyValue 为条件运算符添加了集合运算功能,以便您针对多个条件值测试多个请求值。此外,如果在策略中包含带有通配符或变量的多值字符串键,则还必须使用 StringLike 条件运算符。对于包含单个键的多个值的请求,必须将条件键值括在方括号内,就像数组一样。例如:"Key2":["Value2A", "Value2B"]

  • ForAllValues – 与多值条件键一起使用。测试请求集的每个成员的值是否为条件键集的子集。如果请求中的每个键值均与策略中的至少一个值匹配,则条件返回 true。如果请求中没有键或者键值解析为空数据集(如空字符串),则也会返回 true。不要使用带有 Allow 效果的 ForAllValues,因为这样可能会过于宽容。

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

    注意

    单值条件键和多值条件键之间的差异取决于请求上下文中的值数量,而不是策略条件中的值数量。

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

您可以创建一个策略,以根据您在策略中指定的一个或多个值测试请求中的多个值。假设有一个名为 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,该策略不会拒绝该请求。(为使请求取得成功,必须由不同的策略显式允许它。此策略没有显式拒绝它,但所有请求都被隐式拒绝。)

警告

当您使用 ForAllValues 条件运算符时,如果请求中没有键或者键值解析为空数据集(如空字符串),则返回 true。如需要求该请求至少包含一个值,则您必须在策略中使用另一个条件。有关示例,请参阅在 Amazon 请求期间控制访问

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

本部分讨论有关与 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。