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

创建测试多个键值的条件 (集合运算)

本主题将讨论如何创建允许您测试请求中单个键的多个值的策略 Condition 元素。实际上,您可以创建使用集合运算的条件。这类条件对创建允许精细控制 DynamoDB 表的策略非常有用 (例如,允许或拒绝访问特定属性)。

要创建这类条件,您可以将 ForAllValuesForAnyValue 限定词与条件运算符搭配使用。这些限定词为条件运算符添加了集合运算功能,以便您针对多个条件值测试多个请求值。

介绍

在某些情况下,您需要创建一个策略,允许您根据策略中指定的一个或多个值测试请求中的多个值。请求 Amazon DynamoDB 表的属性就是一个很好的例子。假设有一个名为 Thread 的 Amazon DynamoDB 表用来存储某技术支持论坛中有关话题的信息。该表可能有以下属性,如 IDUserNamePostDateTimeMessageTags 等等。

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

您可能希望通过创建策略仅允许用户查看部分属性,例如仅允许用户查看 PostDateTimeMessageTags。如果 用户请求包含这些属性中的任何一种,都是允许的;但是,如果请求包含任何其他属性 (例如,ID),则请求会被拒绝。从逻辑上讲,您希望创建一个允许属性 (PostDateTimeMessageTags) 列表,并在策略中说明用户请求的所有属性都必须在这个允许的属性列表中。

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

为了支持这些情况,您可以在条件运算符中使用以下修饰符:

  • ForAnyValue – 如果请求中的任何一个键值与策略中的任何一个条件值匹配,则该条件将返回 true。

    注意

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

  • ForAllValues – 如果请求中的每个指定的键值都与策略中至少一个值匹配,则该条件将返回 true。

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

条件集合运算符示例

以下示例策略显示如何将 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 无法使用这些键属性执行所请求的操作。

以下示例说明如何使用 ForAnyValue 限定词以在用户尝试执行 PutItem 操作时拒绝对 IDPostDateTime 属性的访问。也就是说,在用户尝试更新 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" ] } } } }

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

假设用户改为只请求对 UserName 属性执行 PutItem。请求中没有任何属性 (仅 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。