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

配置受 MFA 保护的 API 访问

利用 IAM 策略,可以指定用户可调用的 API。在一些情况下,您可能希望先要求用户通过 AWS Multi-Factor Authentication (MFA) 进行身份验证,然后才允许用户执行特别敏感的操作,从而提高安全性。

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

概述

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

  1. 管理员为每个用户配置 AWS MFA 设备,这些用户需要发出要求 MFA 身份验证的 API 请求。启用 MFA 设备 中介绍了此过程。

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

  3. 用户调用支持 MFA 参数 AssumeRoleGetSessionToken 的 STS API 之一,具体取决于 MFA 保护的方案,如稍后所述。作为调用的一部分,用户包含与其关联的设备的设备标识符,以及该设备生成的基于时间的一次性密码 (TOTP)。在任一情况下,用户都会取回稍后用来向 AWS 发出其他请求的临时安全凭证。

    注意

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

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

带 MFA 条件的 IAM 策略

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

  • IAM 用户或组

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

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

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

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

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

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

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

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

在 GetSessionToken 和 AssumeRole 之间选择

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

对这些方案使用 GetSessionToken

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

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

对这些方案使用 AssumeRole

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

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

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

了解 API 的 MFA 保护的以下几个方面很重要:

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

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

  • 无法向联合身份用户分配 MFA 以与 AWS 产品搭配使用,因此,联合身份用户无法访问受 MFA 控制的 AWS 资源。(请参阅下一个要点。)

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

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

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

  • 要建立 API 的 MFA 保护,可将 MFA 条件添加到策略。如果策略不包含 MFA 的条件,则该策略不会强制使用 MFA。对于跨账户委派,如果角色的信任策略不包含 MFA 条件,则不会使用该角色的临时安全凭证为 API 调用建立 MFA 保护。

  • 如果您允许其他 AWS 账户访问您账户中的资源,即使您要求多重验证,您的资源安全性也取决于可信账户 - 即其他账户 (而不是您的) 的配置。有权创建虚拟 MFA 设备的可信账户中的任何标识都可以构建 MFA 索赔,以满足您角色的信任策略的该部分。在允许其他账户访问要求多重验证的 AWS 资源之前,您应确保可信账户所有者遵循安全最佳实践,并且仅允许特定的可信身份访问敏感 API 的访问 (如 MFA 设备管理 API)。

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

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

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

假设您有一个账户 A (拥有要访问的资源的信任账户),其 IAM 用户 Alice 拥有管理员权限。她希望向账户 B (可信账户) 中的用户 Bob 授予访问权,但希望确保 Bob 在代入该角色之前已使用 MFA 进行身份验证。

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

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"AWS": "ACCOUNT-B-ID"}, "Action": "sts:AssumeRole", "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} } }
  2. Alice 在该角色中添加一个权限策略,以指定允许该角色执行的操作。具有 MFA 保护的角色权限策略与任何其他角色权限策略没有差别。下面的示例演示 Alice 添加到角色中的策略;它允许代入用户对账户 A 中的表 Books 执行任何 DynamoDB 操作。

    注意

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

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["dynamodb:*"], "Resource": ["arn:aws-cn:dynamodb:region:ACCOUNT-A-ID:table/Books"] }] }
  3. 在可信账户 B 中,管理员确保 IAM 用户 Bob 已使用 AWS MFA 设备进行配置,并且该用户了解设备 ID - 即序列号 (如果设备为硬件 MFA 设备) 或设备的 ARN (如果设备为虚拟 MFA 设备)。

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

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

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

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

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

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

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

在此方案中,用户 Carol 是可信用户之一。用户 Alice 是账户 A 中的管理员。

  1. Alice 确保 Carol 已使用 AWS MFA 设备进行配置,并且 Carol 知道设备的 ID,即序列号 (如果设备为硬件 MFA 设备) 或设备的 ARN (如果设备为虚拟 MFA 设备)。

  2. Alice 创建一个名为 EC2-Admins 的组并将用户 Carol 添加到该组中。

  3. Alice 将以下策略附加到 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. 如果用户 Carol 需要停止或终止 Amazon EC2 实例,则她 (或她正在运行的应用程序) 可调用 GetSessionToken 来传递 MFA 设备的 ID 以及 Carol 从其设备获取的当前 TOTP。

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

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

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

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

此方案介绍了一种提供跨账户 MFA 保护的方法,无需用户先担任角色。如果用户已使用 MFA 进行身份验证并且能够从 GetSessionToken 中获取临时安全凭证,且该用户的账户受资源策略的信任,则该用户可访问资源。

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

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

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

  2. Alice 向该存储桶添加存储桶策略。该策略允许账户 A、账户 B 或账户 C 中的所有用户执行存储桶中的 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-cn: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 中,管理员将确保用户 Charlie 已使用 AWS MFA 设备进行配置,并且该用户知道设备的 ID,即序列号 (如果设备为硬件 MFA 设备) 或设备的 ARN (如果设备为虚拟 MFA 设备)。

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

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

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

    注意

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