如何使用我的 Amazon Cognito 用户群体中记住的设备?

3 分钟阅读
0

我想跟踪 Amazon Cognito 用户群体中的用户用于登录我的应用程序的设备。

简短描述

Amazon Cognito 可以跟踪和记忆用户群体中的用户用于登录的设备。通过设备记忆功能,您可以设置登录限制,例如限制从单台设备登录。您还可以让用户在同一台设备上跳过重复登录。有关更多信息,请参阅指定用户群体设备跟踪设置

**注意:**您必须使用 USER_SRP_AUTH 身份验证流才能使用设备跟踪功能。要使用记住的设备取代多重身份验证(MFA),还必须为用户群体启用 MFA

记住设备流程由两部分组成:

  • 确认新设备: 从设备启动身份验证,然后使用 Amazon Cognito 进行确认,获取唯一的设备标识符。
  • 验证已确认的设备: 从已确认的设备启动身份验证,以便在后续登录尝试时跳过 MFA 步骤。

解决方法

**注意:**这些说明描述了在您的应用程序客户端代码中进行的 Amazon Cognito API 调用。如果您使用客户端 SDK,例如 AWS Mobile SDK,则该 SDK 会处理大部分实施。

设置记住的设备

  1. Amazon Cognito 控制台中,选择管理用户群体,然后选择您的用户群体。
  2. 在导航窗格的常规设置下,选择设备
  3. 是否要记住用户的设备中,选择始终用户选择加入。有关更多信息,请参阅使用 Amazon Cognito 跟踪和记住您用户群体中的设备
  4. 对于您是否想要在多重身份验证(MFA)期间使用记住的设备阻止第二因素,请选择。有关更多信息,请参阅使用记住的设备来阻止多重身份验证(MFA)
    **注意:**如果未显示这些选项,则表示未激活 MFA。要设置 MFA,请在导航窗格中选择 MFA 和验证
  5. 选择保存更改

调用 SetUserMFAPreference

在应用程序客户端的代码中,调用 SetUserMFAPreference API,将您使用的 MFA 方法的 MFA 首选项设置为 true

调用 InitiateAuth

在应用程序客户端的代码中,调用 InitiateAuth API 以获取设备密钥。在此 API 请求中,请包含以下请求参数

  • **AuthFlow:**使用 USER_SRP_AUTH
  • **AuthParameters:**包括身份验证参数 USERNAMESRP_ASECRET_HASH
    **注意:**仅当您的应用程序客户端配置了客户端密钥时,才需要 SECRET_HASH

使用以下公式计算 SRP_A
SRP_A = ga (mod N)

  • 按照 AuthenticationHelper.js 中的定义使用 g。有关 g 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js
  • 假设 a = 128 个随机字节

有关更多信息,请参阅请求语法所选 AWS SDK 的 API 参考

为 MFA 质询调用 RespondToAuthChallenge

在您的应用程序客户端调用 InitiateAuth API 后,您的 Amazon Cognito 用户群体会返回一组 MFA 质询。MFA 质询基于您激活的 MFA 方法

您的应用程序必须使用 RespondToAuthChallenge API 来应答这些质询。例如,如果您在用户群体中激活了 SMS 短信 MFA,则在参数中加入值为 SMS_MFAChallengeName。有关更多信息,请参阅请求语法所选 AWS SDK 的 API 参考

存储设备密钥

应答所有 MFA 质询后,Amazon Cognito 会在 NewDeviceMetadataType 字段中以 DeviceGroupKey 和唯一的 DeviceKey 进行响应。

您在浏览器中使用适用于 Android、iOS 或 JavaScript 的 AWS Mobile SDK 时,应用程序会将这些密钥自动移至设备的本地存储空间。如果您使用其他 AWS SDK,请务必为您的应用程序设计类似的密钥存储解决方案。

调用 ConfirmDevice

通过 DeviceGroupKeyDeviceKey,使用安全远程密码(SRP)协议创建密钥。这会生成一个 salt 验证器和一个密码验证器。在包含以下请求参数ConfirmDevice API 调用中将其传递给 Amazon Cognito:

  • **AccessToken:**为用户使用有效的访问令牌。
  • **DeviceKey:**使用从 Amazon Cognito 返回的设备唯一密钥。
  • DeviceName:使用您为设备提供的名称。(AWS Mobile SDK 使用用户代理。)
  • **DeviceSecretVerifierConfig:**包括 Salt(16 个随机字节,Base64 编码)和 PasswordVerifier

对于 PasswordVerifier,请使用以下公式:
PasswordVerifier = g( SHA256_HASH(salt + FULL_PASSWORD) ) (mod N)

  • 按照 AuthenticationHelper.js 中的定义使用 g。有关 g 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js
  • 假设 FULL_PASSWORD = SHA256_HASH(DeviceGroupKey + username + ":" + RANDOM_PASSWORD)
  • 假设 RANDOM_PASSWORD = 40 个随机字节,base64 编码
  • 按照 AuthenticationHelper.js 中的定义使用 N。有关 N 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js

有关更多信息,请参阅请求语法所选 AWS SDK 的 API 参考

(可选)调用 UpdateDeviceStatus

在用户群体中设置记住的设备时,如果选择始终,则可以跳过此步骤。如果您选择用户选择加入,则必须包含 UpdateDeviceStatus API 调用。

**注意:**如果您使用适用于 JavaScript 的 Amazon Cognito Identity SDK,则必须改为调用 setDeviceStatusRememberedsetDeviceStatusNotRemembered。有关如何使用适用于 JavaScript 的 Amazon Cognito Identity SDK 的信息,请参阅 GitHub 网站上的用法

您让应用程序的用户可以选择是否记住设备时,您的用户群体中的设备确认会被记录为“未记住”。 您必须询问用户是否想记住设备,然后使用 UpdateDeviceStatus API 发送他们的输入。

**注意:**需要选择加入时,用户必须先选择加入,然后才能记住设备并禁止 MFA 问题。

使用设备密钥调用 InitiateAuth

在应用程序客户端的代码中,调用 InitiateAuth API 来验证记住的设备。在此调用中,将设备密钥包含在请求参数中,如下所示:

  • **AuthFlow:**使用 USER_SRP_AUTH
  • **AuthParameters:**包括身份验证参数 USERNAMESRP_ADEVICE_KEY

有关更多信息,请参阅请求语法所选 AWS SDK 的 API 参考

为 DEVICE_SRP_AUTH 调用 RespondToAuthChallenge

在您的应用程序客户端使用有效的设备密钥进行 InitiateAuth API 调用后,您的 Amazon Cognito 用户群体将返回 PASSWORD_VERIFIER 质询。您必须在质询响应中包含 DEVICE_KEY。然后,您将收到 DEVICE_SRP_AUTH 质询。要进行响应,请调用 RespondToAuthChallenge API 并包含以下请求参数

  • **ChallengeName:**使用 DEVICE_SRP_AUTH
  • **ClientId:**使用有效的应用程序客户端 ID。
  • **ChallengeResponses:**这些响应中包含 USERNAMEDEVICE_KEYSRP_A
    **注意:**对于 SRP_A,请使用这些说明中前面提到的公式。

调用此 API 后,Amazon Cognito 将以另一个质询响应: DEVICE_PASSWORD_VERIFIER。在响应中,您还会获得 ChallengeParameters SECRET_BLOCKSRP_B 的值。您需要 SECRET_BLOCKSRP_B 值来响应质询。

有关更多信息,请参阅请求语法所选 AWS SDK 的 API 参考

为 DEVICE_PASSWORD_VERIFIER 调用 RespondToAuthChallenge

要响应 DEVICE_PASSWORD_VERIFIER 质询,请调用 RespondToAuthChallenge API 并包含以下请求参数

  • **ChallengeName:**使用 DEVICE_PASSWORD_VERIFIER
  • **ClientId:**使用有效的应用程序客户端 ID。
  • **ChallengeResponses:**包括 USERNAMEPASSWORD_CLAIM_SECRET_BLOCKTIMESTAMPPASSWORD_CLAIM_SIGNATUREDEVICE_KEY

按如下方式定义质询响应:

  • 对于 PASSWORD_CLAIM_SECRET_BLOCK,使用 SECRET_BLOCK 的值。
  • 对于 TIMESTAMP,请包括当前时间。(例如,Tue Sep 25 00:09:40 UTC 2018。)
  • 假设 PASSWORD_CLAIM_SIGNATURE = SHA256_HMAC(K_USER, DeviceGroupKey + DeviceKey + PASSWORD_CLAIM_SECRET_BLOCK + TIMESTAMP),base64 编码
  • 假设 K_USER = SHA256_HASH(S_USER)
  • 假设 S_USER = [ ( SRP_B - [ k * [ (gx) (mod N) ] ] )(a + ux) ](mod N)
  • 假设 x = SHA256_HASH(salt + FULL_PASSWORD)
  • 假设 u = SHA256_HASH(SRP_A + SRP_B)
  • 假设 k = SHA256_HASH(N + g)

从您的用户群体获取 JSON Web 令牌

成功响应上一个质询后,您的 Amazon Cognito 用户群体在 AuthenticationResult 中返回 JSON Web 令牌:

{
    "AuthenticationResult": {
        "AccessToken": "...",
        "ExpiresIn": 3600,
        "IdToken": "...",
        "RefreshToken": "...",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}

相关信息

用户群体身份验证流

用户群体参考(AWS 管理控制台)

GitHub 网站上的 CognitoUser.js

AWS 官方
AWS 官方已更新 7 个月前