使用 MFA 保护 API 访问 - Amazon Identity and Access Management
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 MFA 保护 API 访问

利用 IAM policy,可以指定用户可调用哪些 API 操作。您可以通过要求用户使用多重身份验证(MFA)进行身份验证,然后才允许他们执行特别敏感的操作,从而应用额外的安全性。

例如,您可能拥有允许用户执行 Amazon EC2 RunInstancesDescribeInstancesStopInstances 操作的策略。但您可能希望限制破坏性操作(如 TerminateInstances),并确保用户只能在使用 Amazon MFA 设备进行身份验证后执行该操作。

概述

向 API 操作添加 MFA 保护包括以下任务:

  1. 管理员为每个用户配置 Amazon MFA 设备,这些用户必须发出要求 MFA 身份验证的 API 请求。有关更多信息,请参阅 IAM 中的 Amazon 多重身份验证

  2. 管理员为用户创建包含 Condition 元素的策略,以检查用户是否已使用 Amazon MFA 设备进行身份验证。

  3. 用户会调用支持 MFA 参数的 Amazon STS API 操作之一:AssumeRoleGetSessionToken。调用中包含与用户关联的设备的设备标识符,以及该设备生成的基于时间的一次性密码 (TOTP)。在任一情况下,用户都会取回稍后用来向 Amazon 发出其他请求的临时安全凭证。

    注意

    仅在服务支持临时安全凭证时,该服务的 API 操作的 MFA 保护才可用。有关这些服务的列表,请参阅使用临时安全凭证访问 Amazon

如果授权失败,Amazon 将返回“访问被拒绝”错误消息(与任何未授权的访问一样)。由于采用受 MFA 保护的 API 策略,因此,如果用户在未获得有效的 MFA 身份验证的情况下试图调用 API 操作,则 Amazon 将拒绝用户访问策略中指定的 API 操作。如果 API 操作请求的时间戳在策略中指定的允许范围之外,也会拒绝操作。用户必须使用 MFA 代码和设备序列号请求新的临时安全凭证,通过 MFA 重新进行身份验证。

带 MFA 条件的 IAM policy

带 MFA 条件的策略可附加到以下项:

  • 对于 IAM 用户或组:

  • Amazon S3 存储桶、Amazon SQS 队列或 Amazon SNS 主题等资源

  • 可由用户担任的 IAM 角色的信任策略

可使用策略中的 MFA 条件检查以下属性:

  • Existence(存在性)- 如果只是验证用户是否已使用 MFA 进行身份验证,请检查 aws:MultiFactorAuthPresent 密钥在 Bool 条件中是否为 True。仅当用户使用短期凭证验证时,才会有该键。长期凭证,例如访问密钥,不包括此键。

  • Duration (持续时间) - 如果您只希望在 MFA 身份验证后的指定时间内授予访问权限,请使用数值条件类型将 aws:MultiFactorAuthAge 密钥的有效期与某个值(如 3600 秒)进行比较。请注意,如果未使用 MFA,则 aws:MultiFactorAuthAge 键不会显示。

以下示例说明了 IAM 角色的信任策略,该策略包含一个 MFA 条件,用于测试是否存在 MFA 身份验证。利用此策略,Principal 元素中指定的 Amazon Web Services 账户 中的用户(将 ACCOUNT-B-ID 替换为有效的 Amazon Web Services 账户 ID)能够代入此策略附加的角色。但是,此类用户仅在已使用 MFA 进行身份验证的情况下才能够担任角色。

{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"AWS": "ACCOUNT-B-ID"}, "Action": "sts:AssumeRole", "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} } }

有关 MFA 的条件类型的更多信息,请参阅Amazon 全局条件上下文密钥数字条件运算符用于检查条件键是否存在的条件运算符

在 GetSessionToken 和 AssumeRole 之间选择

Amazon STS 提供了两个 API 操作,可供用户传递 MFA 信息:GetSessionTokenAssumeRole。用户调用哪个 API 操作来获取临时安全凭证,取决于采用以下哪个方案。

GetSessionToken 用于以下方案:

  • 调用访问 Amazon Web Services 账户 中的资源的 API 操作,该账户与发出请求的 IAM 用户相同。请注意,来自 GetSessionToken 请求的临时凭证在您将 MFA 信息包含在凭证请求中时才能访问 IAM 和 Amazon STS API 操作。由于 GetSessionToken 返回的临时凭证包含 MFA 信息,因此您可以检查由该凭证发出的单个 API 操作中的 MFA。

  • 访问受基于资源且包含 MFA 条件的策略所保护的资源。

GetSessionToken 操作旨在使用 MFA 验证用户身份。您不能使用策略来控制身份验证操作。

AssumeRole 用于以下方案:

  • 调用访问相同或不同 Amazon Web Services 账户 中的资源的 API 操作。API 调用可包含任何 IAM 或 Amazon STS API。请注意,要保护访问,您可以在用户担任角色时强制执行 MFA。由 AssumeRole 返回的临时凭证未将 MFA 信息包含在上下文中,因此您无法检查单个 API 操作的 MFA。这就是您必须使用 GetSessionToken 限制对受基于资源的策略保护的资源的访问的原因。

本文档稍后将提供有关如何实现这些方案的详细信息。

有关受 MFA 保护的 API 访问的要点

了解 API 操作的 MFA 保护的以下几个方面非常重要:

  • MFA 保护仅通过使用临时安全凭证提供,而该凭证必须使用 AssumeRoleGetSessionToken 获取。

  • 无法将受 MFA 保护的 API 访问与 Amazon Web Services 账户根用户凭证配合使用。

  • 无法将受 MFA 保护的 API 访问与 U2F 安全密钥配合使用。

  • 将 MFA 设备与 Amazon 服务配合使用时,无法向联合身份用户分配这些设备;因此,这些用户无法访问受 MFA 控制的 Amazon 资源。(请参阅下一个要点。)

  • 返回临时凭证的其他 Amazon STS API 操作不支持 MFA。对于 AssumeRoleWithWebIdentityAssumeRoleWithSAML,用户通过外部提供程序进行身份验证,并且 Amazon 无法确定该提供程序是否需要 MFA。对于 GetFederationToken,MFA 不一定要与特定用户相关联。

  • 同样,长期凭证(IAM 用户访问密钥和根用户访问密钥))无法用于受 MFA 保护的 API 访问,因为它们不会过期。

  • 此外,可以在没有 MFA 信息的情况下调用 AssumeRoleGetSessionToken。在此情况下,发起人将取回临时安全凭证,但这些临时凭证的会话信息不指示使用 MFA 进行身份验证的用户。

  • 要建立 API 操作的 MFA 保护,可将 MFA 条件添加到策略。策略必须包含 aws:MultiFactorAuthPresent 条件键以强制使用 MFA。对于跨账户委派,角色的信任策略必须包含条件键。

  • 如果您允许其他 Amazon Web Services 账户 访问您账户中的资源,则您的资源安全性取决于受信任账户(另一个账户,而不是您的账户)的配置。即使在您强制实施多重身份验证时,也是如此。有权创建虚拟 MFA 设备的受信任账户中的任何标识都可以构建 MFA 索赔,以满足您角色的信任策略的该部分。在允许其他账户的成员访问必须进行多重身份验证的 Amazon 资源之前,您应确保受信任账户的所有者遵循安全最佳实践。例如,受信任账户应仅允许特定的受信任身份访问敏感 API 操作,例如 MFA 设备管理 API 操作。

  • 如果策略包含 MFA 条件,则在以下情况下,将拒绝请求:用户未进行 MFA 身份验证或用户提供了无效的 MFA 设备标识符或无效的 TOTP。

方案:跨账户委派的 MFA 保护

在此方案中,您希望将访问权委托给另一账户中的 IAM 用户,但前提是该用户已使用 Amazon MFA 设备进行身份验证。有关跨账户委派的更多信息,请参阅角色术语和概念

假设您有一个账户 A(拥有待访问资源的信任账户)以及 IAM 用户 Anaya,她拥有管理员权限。她希望向账户 B(受信任账户)中的用户 Richard 授予访问权,但希望确保 Richard 在担任该角色之前已使用 MFA 进行身份验证。

  1. 在信任账户 A 中,Anaya 创建一个名为 CrossAccountRole 的 IAM 角色,并将该角色的信任策略中的主体设置为账户 B 的账户 ID。此信任策略授予对 Amazon STS AssumeRole 操作的权限。Anaya 还向信任策略添加 MFA 条件,如以下示例中所示。

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"AWS": "ACCOUNT-B-ID"}, "Action": "sts:AssumeRole", "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} } }
  2. Anaya 在该角色中添加一个权限策略,以指定允许该角色执行的操作。具有 MFA 保护的角色权限策略与任何其他角色权限策略没有差别。以下示例说明了 Anaya 添加到角色的策略;该策略允许担任该角色的用户对账户 A 中的表 Books 执行任何 Amazon DynamoDB 操作。此策略还允许 dynamodb:ListTables 操作,此操作是在控制台中执行操作所必需的。

    注意

    该权限策略不包含 MFA 条件。了解 MFA 身份验证仅用于确定用户是否可以担任此角色很重要。在用户担任此角色后,将不会进行进一步的 MFA 检查。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "TableActions", "Effect": "Allow", "Action": "dynamodb:*", "Resource": "arn:aws:dynamodb:*:ACCOUNT-A-ID:table/Books" }, { "Sid": "ListTables", "Effect": "Allow", "Action": "dynamodb:ListTables", "Resource": "*" } ] }
  3. 在受信任账户 B 中,管理员确保已使用 Amazon MFA 设备配置 IAM 用户 Richard,并且该用户知道设备的 ID。设备 ID 是序列号(如果是硬件 MFA 设备)或设备的 ARN(如果是虚拟 MFA 设备)。

  4. 在账户 B 中,管理员将以下策略附加到用户 Richard(或该用户所在的组),该策略允许该用户调用 AssumeRole 操作。资源被设置到 Anaya 在第 1 步中创建的角色的 ARN。注意,该策略不包含 MFA 条件。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["sts:AssumeRole"], "Resource": ["arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole"] }] }
  5. 在账户 B 中,Richard(或 Richard 正在运行的应用程序)调用 AssumeRole。API 调用包含要担任角色的 ARN (arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole)、MFA 设备的 ID 和 Richard 从其设备中获取的当前 TOTP。

    当 Richard 调用 AssumeRole 时,Amazon 将确定他是否拥有有效的凭证,包括 MFA 要求。如果是这样的话,Richard 将成功担任角色,并且可在使用角色的临时凭证时对账户 A 中名为 Books 的表执行任何 DynamoDB 操作。

    有关调用 AssumeRole 的程序的示例,请参阅使用 MFA 身份验证调用 AssumeRole

方案:当前账户中 API 操作访问的 MFA 保护

在此方案中,您应确保仅当您 Amazon Web Services 账户 中的用户已使用 Amazon MFA 设备进行身份验证后才能访问敏感 API 操作。

假设您拥有账户 A,其中包含一组需要使用 EC2 实例的开发人员。普通开发人员可以使用实例,但他们未获得 ec2:StopInstancesec2:TerminateInstances 操作的权限。您希望仅允许几个受信任用户执行这些“破坏性”特权操作,因此您将 MFA 保护添加到允许这些敏感 Amazon EC2 操作的策略中。

在此方案中,用户 Sofía 是受信任用户之一。用户 Anaya 是账户 A 中的管理员。

  1. Anaya 确保已使用 Amazon MFA 设备配置 Sofía,并且 Sofía 知道该设备的 ID。设备 ID 是序列号(如果是硬件 MFA 设备)或设备的 ARN(如果是虚拟 MFA 设备)。

  2. Anaya 创建一个名为 EC2-Admins 的组并将用户 Sofía 添加到该组中。

  3. Anaya 将以下策略附加到 EC2-Admins 组。此策略授予用户调用 Amazon EC2 StopInstancesTerminateInstances 操作的权限,但前提是该用户已使用 MFA 进行身份验证。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ec2:StopInstances", "ec2:TerminateInstances" ], "Resource": ["*"], "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} }] }
  4. 注意

    要使此策略生效,用户必须先注销,然后重新登录。

    如果用户 Sofía 需要停止或终止 Amazon EC2 实例,则她(或她正在运行的应用程序)可调用 GetSessionToken。此 API 操作传递 MFA 设备的 ID 和 Sofía 从其设备获取的当前 TOTP。

  5. 用户 Sofía(或 Sofía 正在使用的应用程序)使用由 GetSessionToken 提供的临时凭证来调用 Amazon EC2 StopInstancesTerminateInstances 操作。

    有关调用 GetSessionToken 的程序的示例,请参阅本文档后面的 使用 MFA 身份验证调用 GetSessionToken

方案:拥有基于资源的策略的资源的 MFA 保护

在此方案中,您是 S3 存储桶、SQS 队列或 SNS 主题的所有者。您希望确保访问资源的任何 Amazon Web Services 账户 中的任何用户都已使用 Amazon MFA 设备进行身份验证。

此方案介绍了一种提供跨账户 MFA 保护的方法,无需用户先担任角色。在此情况下,用户可在满足以下三个条件时访问资源:用户已使用 MFA 进行身份验证、能够从 GetSessionToken 获取临时安全凭证且在受资源策略信任的账户中。

假设您在账户 A 中并创建一个 S3 存储桶。您希望向几个不同 Amazon Web Services 账户 中的用户授予对此存储桶的访问权,但前提是这些用户已使用 MFA 进行身份验证。

在此方案中,用户 Anaya 是账户 A 中的管理员。用户 Nikhil 是账户 C 中的 IAM 用户。

  1. 在账户 A 中,Anaya 创建一个名为 Account-A-bucket 的存储桶。

  2. Anaya 向该存储桶添加存储桶策略。该策略允许账户 A、账户 B 或账户 C 中的所有用户执行存储桶中的 Amazon S3 PutObjectDeleteObject 操作。该策略包含 MFA 条件。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": [ "ACCOUNT-A-ID", "ACCOUNT-B-ID", "ACCOUNT-C-ID" ]}, "Action": [ "s3:PutObject", "s3:DeleteObject" ], "Resource": ["arn:aws:s3:::ACCOUNT-A-BUCKET-NAME/*"], "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} }] }
    注意

    Amazon S3(仅)针对账户访问提供“MFA 删除”功能。在您设置存储桶的版本化状态时,可启用 Amazon S3 MFA Delete 功能。Amazon S3 MFA Delete 功能不适用于 IAM 用户,在管理时独立于 MFA 保护的 API 访问。即使 IAM 用户具有删除存储桶的权限,但在启用 Amazon S3 MFA Delete 功能时,也无法执行删除。有关 Amazon S3 MFA Delete 功能的更多信息,请参阅 MFA Delete

  3. 在账户 C 中,管理员确保已使用 Amazon MFA 设备配置用户 Nikhil,并且该用户知道设备的 ID。设备 ID 是序列号(如果是硬件 MFA 设备)或设备的 ARN(如果是虚拟 MFA 设备)。

  4. 在账户 C 中,Nikhil(或他正在运行的应用程序)将调用 GetSessionToken。此调用包括 MFA 设备的 ID 或 ARN 以及 Nikhil 从其设备中获取的当前 TOTP。

  5. Nikhil(或他正在使用的应用程序)使用 GetSessionToken 返回的临时凭证调用 Amazon S3 PutObject 操作以将文件上传到 Account-A-bucket

    有关调用 GetSessionToken 的程序的示例,请参阅本文档后面的 使用 MFA 身份验证调用 GetSessionToken

    注意

    在此情况下,AssumeRole 返回的临时凭证将不可用。尽管用户可以提供 MFA 信息来担任角色,但 AssumeRole 返回的临时凭证不包含 MFA 信息。需要此信息才能满足策略中的 MFA 条件。