Logo
Section 1 / 5

评估流程

了解 IAM 在允许或拒绝请求时所采取的步骤。

检查点

评估流程

了解 IAM 在允许或拒绝请求时所采取的步骤。

现在我们已经讨论了IAM如何看待请求以及控制访问的策略工作原理,接下来需要了解其判断请求是否被允许或拒绝的具体步骤。

第一步:构建请求上下文

首先,系统会根据我们在访问元素课程中讨论的内容构建请求上下文。该上下文包括以下要素:

  • 主体(Principal):发起请求的实体;
  • 操作(Action):描述正在执行的动作;
  • 资源(Resource):操作的目标AWS实体;
  • 以及其他附加到请求上的元数据(metadata)。

遗憾的是,我们对这一步的结果了解有限。可以推测这是一个键值结构,其中每个键都来自请求本身。

例如,当用户向AWS发送请求以读取S3存储桶中的对象时,请求上下文可能如下所示:

1主体:arn:aws:iam::<id>:user/user1 2操作:s3:GetObject 3资源:<bucket>/text.txt

这些值直接来源于操作内容:主体对某个资源执行某项操作。随后,IAM会用其他可用信息填充元数据:

1主体:arn:aws:iam::<id>:user/user1 2操作:s3:GetObject 3资源:<bucket>/text.txt 4aws:SourceIp: 203.0.113.0 5aws:MultiFactorAuthPresent: true 6aws:MultiFactorAuthAge: 3000

上述请求上下文包含了请求来源的IP地址 aws:SourceIp,以及用户使用MFA设备进行认证的信息 aws:MultiFactorAuthPresent 与 aws:MultiFactorAuthAge。实际上,请求上下文包含的信息远不止这些,还包括主体的用户名和用户ID、附加到资源上的标签,以及请求是否通过SSL传输。

注意:请求上下文中确切的值并不明确。我们只能通过阅读文档来推测它们可能是什么。

第二步:收集所有适用的策略

下一步是收集所有适用的策略。正如我们在过滤器课程中所见,大多数IAM策略的属性用于指定该策略适用于哪些请求。IAM会检查所有策略,结合上一步构建的请求上下文,并逐一评估每条策略中的各个过滤条件。此步骤的目标是排除所有不匹配当前请求的策略。

注意:此过程是针对每条策略单独执行的。只有当一条策略的所有过滤条件都与请求上下文匹配时,它才会进入下一步。

举个例子,考虑一个附加到名为 user1 的用户的基于身份的策略。在这种情况下,Principal 元素是隐含的:

1{ 2 "Effect": "Allow", 3 "Action": "s3:*", 4 "Resource": "*" 5}

将其与以下请求上下文进行匹配:

1主体:arn:aws:iam::<id>:user/user1 2操作:s3:GetObject 3资源:<bucket>/text.txt

该策略中的过滤条件为 "Action": "s3:*"、"Resource": "*",以及由于策略附加在 user1 上,因此 Principal 也隐含为 user1。

过滤条件值是否匹配?
Action: s3:*s3:GetObject✔
Principal: user1user1✔
Resource: */text.txt✔

由于所有过滤条件均匹配,该策略将在下一步中被使用。

但如果请求是由另一个用户 user2 发起的,请求上下文中的主体就不同了:

1主体:arn:aws:iam::<id>:user/user2 2操作:s3:GetObject 3资源:<bucket>/text.txt

此时,该策略的过滤条件不再匹配此请求,因此不会进入下一步。

过滤条件值是否匹配?
Action: s3:*s3:GetObject✔
Principal: user1user2-
Resource: */text.txt✔

注意:在此步骤中,策略的 Effect 是 "Allow" 还是 "Deny" 并不重要。IAM仅负责收集与请求匹配的策略。是否允许或拒绝访问将在下一步处理。

基于资源的策略可以定义 Principal 元素来指定其适用的实体。下面这个策略允许 user1 读取存储桶中的对象:

1{ 2 "Effect": "Allow", 3 "Action": "s3:GetObject", 4 "Principal": { 5 "AWS": "arn:aws:iam::<id>:user/user1" 6 }, 7 "Resource": "<bucket>/*" 8}

当 user1 尝试读取对象时,该策略匹配。

过滤条件值是否匹配?
Action: s3:GetObjects3:GetObject✔
Principal: user1user1✔
Resource: /*/text.txt✔

但当 user2 执行相同操作时,则不匹配:

过滤条件值是否匹配?
Action: s3:GetObjects3:GetObject✔
Principal: user1user2-
Resource: /*/text.txt✔

此过程同样适用于否定值。例如,当资源策略中定义了 NotPrincipal 时,它会影响那些不在策略中的用户:

1{ 2 "Effect": "Allow", 3 "Action": "s3:GetObject", 4 "NotPrincipal": { 5 "AWS": "arn:aws:iam::<id>:user/user2" 6 }, 7 "Resource": "<bucket>/*" 8}

由 user1 发起的请求将通过所有过滤条件:

过滤条件值是否匹配?
Action: s3:GetObjects3:GetObject✔
NotPrincipal: user2user1✔
Resource: /*/text.txt✔

但由 user2 发起的相同请求则不会通过:

过滤条件值是否匹配?
Action: s3:GetObjects3:GetObject✔
NotPrincipal: user2user2-
Resource: /*/text.txt✔

同样的逻辑也适用于 NotAction 和 NotResource 元素。

最后,Condition 元素用于检查请求上下文中的元数据。以下这个基于资源的策略要求必须使用MFA设备进行认证:

1{ 2 "Version": "2012-10-17", 3 "Statement": { 4 "Effect": "Deny", 5 "Principal": "*", 6 "Action": "*", 7 "Resource": "<bucket>/*", 8 "Condition": { 9 "Bool": { 10 "aws:MultiFactorAuthPresent": "false" 11 } 12 } 13 } 14}

当用户使用MFA设备时,该策略不匹配:

过滤条件值是否匹配?
Action: *s3:GetObject✔
Principal: *user1✔
Resource: /*/text.txt✔
aws:MultiFactorAuthPresent: falsetrue-

相反,当未使用MFA设备时,该策略则匹配:

过滤条件值是否匹配?
Action: *s3:GetObject✔
Principal: *user1✔
Resource: /*/text.txt✔
aws:MultiFactorAuthPresent: falsefalse✔

注意:此步骤的结果是一个与请求上下文匹配的策略集合。这些策略将在下一步中使用。

第三步:运行评估逻辑

在通过过滤条件收集到有效的策略语句后,系统将使用策略评估逻辑来决定请求是否被允许。AWS官方文档提供了一张描述性图表,总结了其工作方式:

...
完整的策略评估逻辑

虽然看起来复杂,但图表的大部分内容其实只体现了两个简单原则:

  • 如果存在 Deny,则结果为拒绝。
  • 如果不存在 Allow,则结果为拒绝。

其余部分主要是为了说明哪些策略是“足够”的,哪些是“可选”的。

服务控制策略(SCP)、权限边界和会话级策略属于特定使用场景,是可选的。如果我们没有使用它们,它们就不会影响策略评估,IAM会跳过这些部分。最重要的是基于身份的策略和基于资源的策略。绝大多数策略都属于这两种类型。

当我们去掉那些面向特定场景的部分后,评估逻辑变得简单明了:

...
基于身份和基于资源的策略评估

关键点在于:只要基于资源的策略或基于身份的策略中有一个允许该操作,请求就会被允许。

让我们来测试一下你在这节课中学到的概念!

Quiz

单选题

请求上下文包含来自主体、资源、操作以及附加到请求的任何元数据的信息。

1 / 8

IAM 策略

允许访问