Amazon Cognito のユーザープールで記憶済みデバイスを使用するにはどうすればよいですか?

所要時間3分
0

Amazon Cognito のユーザープールのユーザーがアプリへのサインインに使用するデバイスを追跡したいと考えています。

簡単な説明

Amazon Cognito は、ユーザープール内のユーザーがサインインに使用するデバイスを追跡して記憶できます。デバイスを記憶する機能により、ある 1 つのデバイスからのログインを制限するといった、サインインの制限を設定できます。また、ユーザーが同じデバイスで繰り返しサインインせずに済むようにすることもできます。詳細については、「ユーザープールデバイス追跡設定の指定」を参照してください。

注: デバイストラッキング機能を使用するには、USER_SRP_AUTH 認証フローを使用する必要があります。記憶済みのデバイスを多要素認証 (MFA) の代わりに使用するには、ユーザープールの MFA を有効にすることも必要です。

デバイスを記憶する機能は、次の 2 つの部分で構成されます。

  • 新しいデバイスの確認: デバイスから認証を開始し、Amazon Cognito で確認して一意のデバイス識別子を取得します。
  • 確認済みのデバイスの検証: 確認済みのデバイスから認証を開始し、それ以降のサインイン試行では MFA ステップを省略します。

解決策

注: 以下の手順では、アプリクライアントのコードで行う Amazon Cognito API 呼び出しについて説明します。AWS Mobile SDK などのクライアント側の SDK を使用する場合、SDK が実装の大部分を処理します。

記憶済みのデバイスをセットアップする

  1. Amazon Cognito コンソールで、[ユーザープールを管理] を選択し、次にユーザープールを選択します。
  2. ナビゲーションペインの [全般設定] で、[デバイス] を選択します。
  3. [ユーザーのデバイスを記憶しますか?][常に] または [ユーザーオプトイン] を選択します。詳細については、「Tracking and remembering devices using Amazon Cognito Your User Pools」を参照してください。
  4. [記憶済みのデバイスを使用して、多要素認証 (MFA) 中に 2 つ目の要素を抑制しますか?][はい] または [いいえ] を選択します。詳細については、「記憶済みデバイスを使用した多要素認証 (MFA、Multi-Factor Authentication) の停止」を参照してください。
    注: これらのオプションが表示されない場合、MFA は有効化されていません。MFA をセットアップするには、ナビゲーションペインで [MFA および確認] を選択します。
  5. [変更を保存] を選択します。

SetUserMFAPreference を呼び出す

アプリクライアントのコードで setUserMFAPReference API を呼び出して、使用する MFA メソッドの MFA ユーザー設定を true に設定します。

InitiateAuth を呼び出す

アプリクライアントのコードで、InitiateAuth API を呼び出してデバイスキーを取得します。この API リクエストには、以下のリクエストパラメータを含めます。

  • AuthFlow: USER_SRP_AUTH を使用します。
  • AuthParameters: 認証パラメータとして、USERNAMESRP_A、およびSECRET_HASH を含めます。
    注: **SECRET_HASH ** が必要となるのは、アプリクライアントがクライアントシークレットで構成されている場合のみです。

SRP_A を計算するには次の式を使用します。
SRP_A = ga (mod N)

  • AuthenticationHelper.js で定義されているように g を使用します。g の定義については、GitHub ウェブサイトの AuthenticationHelper.js を参照してください。
  • a = 128のランダムバイトとします

詳細については、「Request Syntax」および選択した AWS SDK の API リファレンスを参照してください。

MFA チャレンジのための RespondToAuthChalleng を呼び出す

お使いのアプリクライアントが InitiateAuth API の呼び出しを行うと、Amazon Cognito ユーザープールは MFA チャレンジのセットを返します。これらの MFA チャレンジは、有効化する MFA メソッドに基づきます。

これらのチャレンジに応答するには、アプリで RespondToAuthChallenge API を使用する必要があります。例えば、ユーザープールで SMS テキストメッセージの MFA を有効化した場合は、パラメーター ChallengeNameSMS_MFA という値を含めます。詳細については、「Request Syntax」および選択した AWS SDK の API リファレンスを参照してください。

デバイスキーを保存する

すべての MFA チャレンジが応答されると、Amazon Cognito は NewDeviceMetadataType フィールドの DeviceGroupKey および一意の DeviceKey で応答します。

AWS Mobile SDK for Android/iOS/JavaScript in the Browser を使用すると、アプリケーションがこれらのキーをデバイスのローカルストレージに自動的に移動します。別の AWS SDK を使用する場合は、必ずお使いのアプリ向けの同様のキーストレージソリューションを設計してください。

ConfirmDevice を呼び出す

DeviceGroupKeyDeviceKey を使用して、Secure Remote Password (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 を参照してください。

詳細については、「Request Syntax」および選択した AWS SDK の API リファレンスを参照してください。

(オプション) UpdateDeviceStatus を呼び出す

ユーザープールに記憶済みのデバイスをセットアップするときに、[常に] を選択するとこの手順を省略できます。[ユーザーオプトイン] を選択した場合は、UpdateDeviceStatus API 呼び出しを含める必要があります。

注: Amazon Cognito Identity SDK for JavaScript を使用する場合は、代わりに setDeviceStatusRemembered または SetDeviceStatusNotRemembered を呼び出す必要があります。Amazon Cognito Identity SDK for JavaScript を使用する方法については、GitHub ウェブサイトの「Usage」を参照してください。

デバイスを記憶させるオプションをアプリのユーザーに付与すると、ユーザープール内のデバイス確認が「未記憶」として追跡されます。' デバイスを記憶させるようにするかどうかをユーザーに確認してから、UpdateDeviceStatus API を使用して入力を送信する必要があります。

注: オプトインが必要な場合は、ユーザーがオプトインしないとデバイスは記憶されず、MFA チャレンジが抑制されます。

デバイスキーを使用して InitiateAuth を呼び出す

アプリクライアントのコードで、InitiateAuth API を呼び出して、記憶済みのデバイスを検証します。この呼び出しでは、次のようにリクエストパラメータにデバイスキーを含めます。

  • AuthFlow: USER_SRP_AUTH を使用します。
  • AuthParameters: 認証パラメータとして、USERNAMESRP_A、およびDEVICE_KEY を含めます。

詳細については、「Request Syntax」および選択した 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_KEY、および SRP_A を含めます。
    注: SRP_A の場合は、前述した式をこれらの手順で使用してください。

この API 呼び出し後、Amazon Cognito はもう 1 つのチャレンジ DEVICE_PASSWORD_VERIFIER で応答します。このレスポンスでは、ChallengeParameters SECRET_BLOCK および SRP_B の値も取得します。チャレンジに応答するには SECRET_BLOCKSRP_B の値が必要です。

詳細については、「Request Syntax」および選択した AWS SDK の API リファレンスを参照してください。

DEVICE_PASSWORD_VERIFIER のための RespondToAuthChallenge を呼び出す

DEVICE_PASSWORD_VERIFIER チャレンジに応答するには、RespondToAuthChallenge API を呼び出して、以下のリクエストパラメータを含めてください。

  • ChallengeName: DEVICE_PASSWORD_VERIFIER を使用します。
  • ClientId: 有効なアプリクライアント ID を使用します。
  • ChallengeResponses: USERNAMEPASSWORD_CLAIM_SECRET_BLOCKTIMESTAMPPASSWORD_CLAIM_SIGNATURE、および DEVICE_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 ウェブトークンを取得する

最後のチャレンジに正常に応答すると、Amazon Cognito ユーザープールは AuthenticationResult に JSON ウェブトークンを返します。

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

関連情報

ユーザープール認証フロー

ユーザープールリファレンス (AWS マネジメントコンソール)

GitHub ウェブサイトの CognitoUser.js

AWS公式
AWS公式更新しました 7ヶ月前
コメントはありません