过滤器:主体、资源和操作
了解IAM策略中可用的前三个过滤元素。
IAM策略是一个具有严格定义结构的JSON文档。它包含一个或多个语句,这些语句是访问控制的基本构建单元。策略本身是这些语句的容器。一个示例策略JSON如下:
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Effect": "Allow", 6 "Action": [ 7 "s3:GetObject" 8 ], 9 "Resource": "<bucket>/text.txt" 10 } 11 ] 12}
无论我们将语句放在单个策略中还是多个策略中,只要它们附加到某个实体上,效果就相同。因此,本课程将策略和语句这两个术语互换使用。
每个语句可以包含一个Effect、一个Action、一个Principal、一个Resource以及一个Condition。根据策略附加到的实体类型,允许使用的参数集也不同。例如,附加到IAM用户的策略不支持Principal元素,因为该信息由关联关系隐含确定。
Effect 只能是 Allow 或 Deny。这决定了该语句是“授予访问权限”还是“拒绝访问权限”。我们将在 评估流程 课程的“第3步:运行评估逻辑”部分详细学习其工作原理。
其余所有元素都是过滤器,用于限制该策略适用于哪些请求。
注意: 策略格式为JSON,不支持尾随逗号。在最后一个元素后保留逗号是常见的错误来源。
1{ 2 "Action": [ 3 "s3:PutObject", 4 "s3:GetObject", // <= 这是无效的 5 ], 6 // ... 7}
让我们测试一下你对本节课内容的理解!
过滤器
当请求到达AWS API时,IAM服务会收集所有与请求匹配的策略。它利用策略中的过滤器元素来判断是否匹配。
下面我们来看看策略中可用的过滤器类型。
提示: 更好地将过滤器理解为“匹配”或“不匹配”请求,而不是“允许操作”或“不允许操作”。语句可以拒绝访问权限,尤其是在使用 Not 前缀时,容易产生混淆。
Principal / NotPrincipal
Principal 元素定义了该策略所匹配的主体。这与请求中的 Principal 元素相对应,正如我们在 主体 课程中讨论的那样。
要指定一个IAM用户,请使用 {"AWS": "<arn>"} 的结构:
1{ 2 "Principal": { 3 "AWS": "<iam>:user/user2" 4 }, 5 // ... 6}
同样的方式也可以用于角色:
1{ 2 "Principal": { 3 "AWS": "<iam>:role/role2" 4 }, 5 // ... 6}
正如我们在 特殊主体 课程中所讲,还有两种常见的主体类型。第一种是匿名用户,用于提供公共访问权限:
1{ 2 "Principal": { 3 "AWS": "*" 4 }, 5 // ... 6}
最后,若要授予AWS服务访问权限,请使用 Service 主体类型:
1{ 2 "Principal": { 3 "Service": "lambda.amazonaws.com" 4 }, 5 // ... 6}
我们还可以在JSON数组中定义多个主体。策略将匹配其中所有值:
1{ 2 "Principal": { 3 "AWS": [ 4 "<iam>:user/user1", 5 "<iam>:user/user2" 6 ] 7 }, 8 // ... 9}
在上述示例中,由 user1 或 user2 发起的请求都会被匹配。
注意: 还存在其他未在此讨论的主体类型。更多详情请参阅 参考文档。
Principal 的对应元素是 NotPrincipal。顾名思义,它匹配列表中不在其中的主体。例如,以下策略匹配除 user1 以外的所有用户:
1{ 2 "NotPrincipal": { 3 "AWS": "<iam>:user/user1" 4 }, 5 // ... 6}
NotPrincipal 元素最常与 Deny 语句结合使用,以创建一个允许访问资源的白名单。我们将在 基于资源的策略 课程中通过示例详细讲解这一场景。
在继续之前,先来做个小测验!
Resource / NotResource
类似地,Resource 过滤器指定了该语句适用的资源。我们已在 资源 课程中讨论过请求中的 Resource 元素。
Resource 元素的结构与 Principal 类似。策略可以匹配特定资源:
1{ 2 "Resource": "arn:aws:s3:::<bucket>", 3 // ... 4}
也可以匹配多个资源:
1{ 2 "Resource": [ 3 "arn:aws:s3:::<bucket1>", 4 "arn:aws:s3:::<bucket2>" 5 ], 6 // ... 7}
它还支持通配符,用于定义匹配的子集。此策略匹配S3存储桶中的所有对象:
1{ 2 "Resource": "arn:aws:s3:::<bucket>/*", 3 // ... 4}
通配符也可用于匹配资源路径的一部分(如果支持)。例如,此策略匹配所有带有 admin/ 路径段的用户:
1{ 2 "Resource": "arn:aws:iam::<accountId>:user/admin/*", 3 // ... 4}
注意: 上述策略在用户作为请求的目标时生效。例如,当请求试图删除
admin/路径下的用户时,该语句才会匹配。
Resource 的对应元素是 NotResource。它匹配所有未被匹配的内容。其行为类似于 NotPrincipal,也最常与 Deny 语句配合使用。例如,以下语句匹配那些不针对指定S3存储桶的请求:
1{ 2 "NotResource": "arn:aws:s3:::<bucket>", 3 // ... 4}
在进入最后一个过滤器元素前,先来做个小测验!
Action / NotAction
Action 元素对请求上下文中的 Action 元素进行限制,这一点我们在 操作 课程中已经讨论过。例如,以下语句匹配 s3:GetObject 操作:
1{ 2 "Action": "s3:GetObject", 3 // ... 4}
与其它元素类似,它也支持定义多个值:
1{ 2 "Action": [ 3 "s3:GetObject", 4 "s3:GetObjectVersion" 5 ], 6 // ... 7}
它还支持通配符。此策略匹配所有针对S3服务的操作:
1{ 2 "Action": "s3:*", 3 // ... 4}
除了匹配服务外,它还支持匹配操作的部分内容。此策略匹配所有以 Get 开头或以 Bucket 结尾的操作:
1{ 2 "Action": [ 3 "s3:Get*", 4 "s3:*Bucket" 5 ], 6 // ... 7}
注意: 在
Action元素中使用通配符是不推荐的。通常意味着策略的范围比应有的更大。此外,它可能还会匹配未来新增的操作。如果AWS将来添加一个以s3:Get开头的新操作,上述策略将自动适用于该操作。
最后,Action 有对应的 NotAction 元素,用于匹配未列出的所有操作。例如,以下策略匹配所有非S3服务的操作:
1{ 2 "NotAction": "s3:*", 3 // ... 4}
如果将 NotAction 与 Allow 效果结合使用,可能会授予超出预期的权限。务必对此组合格外小心。
现在来测试一下你对本节课内容的掌握情况!
Quiz
IAM 策略可以用 JSON 和 YAML 格式编写。