创建具有多个键或值的条件
您可以使用策略的 Condition
元素测试请求中的多个键或单个键的多个值。在以编程方式或通过 Amazon向 Amazon Web Services Management Console 发出请求时,请求包含有关您的主体、操作和标签等的信息。要了解请求中包含的信息和数据,请参阅Request。您可以使用条件键来测试请求中的匹配键的值。例如,您可以使用条件键根据标签控制对 DynamoDB 表的特定属性或 Amazon EC2 实例的访问。
一个 Condition
元素可以包含多个条件,而每个条件又可以包含多个键值对。大多数条件键支持使用多个值。下图对此进行了说明。除非另行指定,否则所有键均可有多个值。

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

当多个值针对否定匹配条件运算符(StringNotEquals
和 DateNotEquals
)在策略中列出时,有效权限会像 AND
那样工作。例如,如果在 StringNotEquals
条件运算符中有多个 aws:PrincipalAccount
值,则字符串无法匹配用来将条件转换为 true 所罗列的 aws:PrincipalAccount
数值。
使用多个键和值
要将条件与具有多个键值的请求上下文进行比较,必须使用 ForAllValues
或者 ForAnyValue
集合运算符。这些限定词为条件运算符添加了集合运算功能,以便您针对多个条件值测试多个请求值。此外,如果在策略中包含带有通配符或变量的多值键,则还必须使用 StringLike
条件运算符。对于包含单个键的多个值的请求,必须将条件括在方括号内,例如数组 ("Key2":["Value2A", "Value2B"])。
-
ForAllValues
- 测试请求集的每个成员的值是否为条件键集的子集。如果请求中的每个键值均与策略中的至少一个值匹配,则条件返回 true。如果请求中没有键或者键值解析为空数据集(如空字符串),则也会返回 true。 -
ForAnyValue
- 测试请求值集的至少一个成员是否与条件键值集的至少一个成员匹配。如果请求中的任何一个键值与策略中的任何一个条件值匹配,则条件返回 true。对于没有匹配的键或空数据集,条件返回 false。
假设您希望仅在一个数值 foo 等于 A 或 B 并且另一个数值 bar 等于 C 时,才让 John 使用资源。应创建如下图所示的条件块。

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

Amazon 具有预定义的条件运算符和键(如 aws:CurrentTime
)。各个 Amazon 服务还会定义服务特定的键。
例如,假设您希望让用户 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 必须满足所有三个条件运算符才能访问您的队列、主题或资源。
条件块在你们策略中的样子如下所示。将使用 aws:SourceIp
评估 OR
的两个值,并使用 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 表用来存储某技术支持论坛中有关话题的信息。该表具有名为 ID
、UserName
、PostDateTime
、Message
和 Tags
的属性。
{
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 的精细访问控制。
您可以创建一个策略以允许用户仅查看 PostDateTime
、Message
和 Tags
属性。如果用户的请求包含其中的任何属性,则允许该请求。但如果请求包含任何其他属性(例如 ID
),则拒绝该请求。从逻辑上讲,您希望创建允许的属性列表 (PostDateTime
, Message
, Tags
)。您还希望在策略中指示,用户请求的所有属性必须位于该允许的属性列表中。
以下示例策略显示如何将 ForAllValues
限定词与 StringEquals
条件运算符搭配使用。该条件仅 允许用户请求名为 Thread
的 DynamoDB 表中的 ID
、Message
或 Tags
属性。
{ "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
表中获取 Message
和 Tags
属性。在这种情况下,允许该请求,因为用户请求的属性均与策略中指定的值匹配。GetItem
操作要求用户将 ID
属性作为数据库表键传递(策略也允许这样做)。不过,如果用户的请求包含 UserName
属性,请求将会失败。原因是 UserName
不在允许的属性列表中,并且 ForAllValues
限定词要求所有请求的值在策略中列出。
如果使用 dynamodb:Attributes
,您必须指定表的所有主键和索引键属性的名称。您还必须指定在策略中列出的任何二级索引。否则,DynamoDB 无法使用这些键属性执行所请求的操作。
或者,您可能希望确保明确禁止用户在请求中包含某些属性,如 ID
和 UserName
属性。例如,您可能会在用户更新 DynamoDB 表时排除一些属性,因为更新(PUT
操作)不应更改特定属性。在这种情况下,您创建禁止的属性列表 (ID
, UserName
)。如果用户请求的任何属性与任何禁止的属性匹配,则拒绝该请求。
以下示例说明如何使用 ForAnyValue
限定词以在用户尝试执行 ID
操作时拒绝对 PostDateTime
和 PutItem
属性的访问。也就是说,在用户尝试更新 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
表的 Message
和 Thread
属性。ForAnyValue
限定词可确定是否有请求的属性在策略列表中出现。在这种情况下,只有一项匹配 (PostDateTime
),因此,条件为 true。假设请求中的其他值也可以满足 (例如,资源),则总策略评估返回 true。因为策略的效果为 Deny
,请求被拒绝。
假设用户改为只请求对 PutItem
属性执行 UserName
。请求中没有任何属性 (仅 UserName
) 与策略中列出的任何属性 (ID
、PostDateTime
) 相匹配。条件将返回 false,因此,策略 (Deny
) 的效果也为 false,该策略不会拒绝该请求。(为使请求取得成功,必须由不同的策略显式允许它。此策略没有显式拒绝它,但所有请求都被隐式拒绝。)
当您使用 ForAllValues
条件运算符时,如果请求中没有键或者键值解析为空数据集(如空字符串),则返回 true。如需要求该请求至少包含一个值,则您必须在策略中使用另一个条件。有关示例,请参阅 在 Amazon 请求期间控制访问。
将多个值与条件集合运算符一起使用的评估逻辑
本部分讨论有关与 ForAllValues
和 ForAnyValue
运算符结合使用的评估逻辑的详细信息。下表显示请求中可能包含的键 (PostDateTime
和 UserName
),以及一个包含 PostDateTime
、Message
和 Tags
值的策略条件。
键 (在请求中) |
条件值(在策略中) |
---|---|
|
|
|
|
|
|
组合的评估如下:
|
|
|
|
|
|
条件运算符结果取决于策略条件使用了哪个修饰符:
-
ForAllValues
. 如果请求中的每个键(PostDateTime
或UserName
)至少与策略中的一个条件值(PostDateTime
、Message
、Tags
)匹配,则条件运算符将返回 true。换言之,为了使条件返回 true,PostDateTime
必须等于PostDateTime
、Message
或Tags
并且UserName
必须等于PostDateTime
、Message
或Tags
。 -
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 请求获取 PostDateTime
和 UserName
属性。组合的评估如下:
|
|
|
|
|
|
|
|
|
|
|
|
策略包含 ForAllValues
条件运算符修饰符,这意味着 PostDateTime
和 UserName
必须至少各有一个匹配项。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
请求包含属性 UserName
、Message
和 PostDateTime
。评估如下:
|
|
|
|
|
|
|
|
|
|
|
|
使用修饰符 ForAnyValue
后,如果任何一个测试返回 true,则条件将返回 true。最后一个测试返回 true,因此条件也将返回 true;因为 Effect
元素设置为 Deny
,因此请求将被拒绝。
如果请求中的键值解析为空数据集(例如,空字符串),ForAllValues
修饰的条件运算符将返回 true。此外,ForAnyValue
修饰的条件运算符返回 false。