AWS Cognito-重置用户MFA

Sta*_*Cub 6 amazon-web-services amazon-cognito cognito mfa

我有有MFA集到Cognito用户池RequiredTOTP只(即没有SMS)。

我的问题是如何为用户重置MFA?例如,如果用户丢失了手机,以致他无从登录,该怎么办。

我曾尝试过重设密码,但是那只会重设密码,不会删除MFA。

在此AWS文档的底部,它说

注意 API中当前不提供删除TOTP软件令牌操作。计划在将来的版本中使用此功能。使用SetUserMFAPreference可以为单个用户禁用TOTP MFA。

因此,我尝试了SetUserMFAPreferenceAdminSetUserMFAPreference,它们只返回200 OK,但实际上并未禁用MFA。我猜这是由于用户池的MFA设置为Required

Meh*_*ran 9

此时,由于 AWS 不支持重置 MFA(如果您的用户池需要 MFA - 禁用 MFA 使用AdminSetUserMFAPreference将返回 200 OK,但不会执行任何操作),因此唯一的方法是创建一个具有可选 MFA 的新用户池(您必须创建一个新的,因为一旦创建用户池就禁止从required到更改)。optional然后,对于新的用户池,您必须在代码中手动强制执行 MFA(如果这是您想要的)。

为此,一旦用户成功登录并且返回对象中包含令牌,您必须调用(AssociateSoftwareToken而不是返回令牌)并启动 MFA 注册过程。IdToken仅当用户成功完成调用时,令牌(例如)才会返回给用户AdminRespondToAuthChallenge

底线是,使用可选的 MFA,AdminSetUserMFAPreference将会起作用。这是在 AWS 上的用户池中重置 MFA 的唯一方法(目前)。

[更新]

并不是说我原来的答案无效,只是为了提供更多信息,这里有一些关于如何使用的额外解释AdminSetUserMFAPreference

首先,您需要一个具有可选MFA 的用户池。可选的是这里的关键字。此解决方案不适用于具有所需 MFA 的用户池。

设置用户池后,我假设有一个用户正确注册到您的用户池。这意味着他们可以毫无问题地针对您的用户池对自己进行身份验证。当然,重点是他们需要提供 MFA 作为身份验证过程的一部分。但由于我们已经确定,MFA 在您的用户池中是可选的,因此如果您坚持对用户强制执行 MFA,则意味着您必须在代码中手动执行此操作。

好吧,到目前为止大家都很开心。但正如现实一样,悲伤的日子也随之而来。您的用户将丢失其 MFA 代码,并且无法生成任何新的 MFA 代码。因此,您希望为他们提供通过重新注册新设备来重置 MFA 的可能性。当然,首先,您需要确保这是真正的用户请求这样的事情。我的意思是您不希望任何人(除了真正的用户)能够提出这样的请求。所以你需要先验证它们。但他们无法进行身份验证(由于缺少 MFA)这一事实是他们最终来到这里的全部原因。那么你现在能做什么呢?好吧,尽管这部分超出了本文的范围,但作为一个小提示,您可以向他们发送一封包含代码的电子邮件,并要求他们将其返回给您,作为一次性身份验证机制。

好吧,回到手头的问题。现在,您确定是实际的帐户所有者在请求 MFA 重置。这就是你如何做到的:

async function resetMfa(username) {
    const cognito = new AWS.CognitoIdentityServiceProvider();
    await cognito.adminSetUserMFAPreference({
            UserPoolId: "user pool ID",
            Username: username,
            SoftwareTokenMfaSettings: {
                Enabled: false,
            }
        }).promise();
}
Run Code Online (Sandbox Code Playgroud)

一旦 MFA 被禁用,为了重新注册新设备,帐户所有者必须尝试新的登录。此尝试就像他们第一次登录帐户一样,系统会要求他们注册新的 MFA 设备。

我希望这能让事情变得更清楚一些。如果您想了解如何(手动)使用 MFA,我有另一篇文章解决了这个问题。


Tom*_* Q. -1

您可以为每个用户提供一个恢复代码,然后编写一个通过 API 端点公开的 Lambda,检查他们是否提交了正确的恢复代码。如果这样做,您可以在 Lambda 中调用以下命令来禁用用户的 MFA:

  const result = await cognito
    .adminSetUserMFAPreference({
      UserPoolId: AmplifyConfig.Auth.userPoolId,
      Username: userid,
      SoftwareTokenMfaSettings: {
        Enabled: false,
        PreferredMfa: false,
      },
    })
    .promise();
Run Code Online (Sandbox Code Playgroud)

在检查这些恢复代码时,请务必使用类似的方法crypto.timingSafeEqual来防御定时攻击。