多要素認証を構成する

このページでは、メールで確認コードを送信してユーザーの ID 確認を行う多要素認証(MFA)の構成方法について説明します。この機能を使用すると、ユーザーがアカウントに関連付けられたメールアドレスを所有していることを確認できます。MFA は、クレデンシャル スタッフィングやアカウントの乗っ取り(ATO)からユーザーを保護するのに役立ちます。

MFA はスコアベースのキーで使用できますが、チェックボックスのキーでは使用できません。

MFA の構成プロセスについて

reCAPTCHA の MFA 機能は、通常の reCAPTCHA ワークフローの上に実装されます。

MFA ワークフローの概要は次のとおりです。

  1. ウェブサイトでの重要なワークフローをインストルメント化します
  2. execute() 呼び出しによって返されたトークンと MFA パラメータを使用して評価を作成し、MFA requestToken を取得します。
  3. 使用するチャネルに応じて requestToken を使用して MFA チャレンジをトリガーします(メールのみサポート)。
  4. ウェブサイトでエンドユーザーが入力した PIN を確認します。
  5. 確認リクエストで返されたトークンを使用して、新しい評価を作成します。

準備

  1. reCAPTCHA 用に環境を準備します

  2. MFA は、プロジェクトに請求先アカウントを追加したときに開始されるセキュリティ審査後にアクセスできます。 この機能をサイトにオンボーディングするには、請求先アカウントを追加します。

  3. MFA のメール確認機能を有効にするには、次の操作を行います。

    1. Google Cloud コンソールで、[reCAPTCHA] ページに移動します。

      [reCAPTCHA] に移動

    2. リソース セレクタにプロジェクトの名前が表示されていることを確認します。

      プロジェクトの名前が表示されない場合は、リソース セレクタをクリックしてプロジェクトを選択します。

    3. [設定] をクリックします。

    4. [多要素認証] ペインで [構成] をクリックします。

    5. [多要素認証を構成] ダイアログで、次の操作を行います。

      1. メール確認を有効にするには、[メールを有効にする] 切り替えボタンをクリックします。
      2. [送信者名] ボックスに名前を入力します。
      3. [送信者のメールアドレス] ボックスに、メールアドレスを入力します。

    6. [保存] をクリックします。

  4. スコアベース キーを使用してウェブサイトに reCAPTCHA を設定します

ウェブサイトでの重要なワークフローをインストルメント化する

リスク評価の execute() 関数を使用して、reCAPTCHA に必要な情報を渡します。execute() 関数は、トークンの生成時に解決される Promise を返します。

次のサンプルコードに示すように、execute() 関数に twofactor パラメータを追加します。

  grecaptcha.enterprise.execute(KEY_ID, {
    action: 'login',
    twofactor: true
  }).then(token => {
    // Handle the generated token.
  });

KEY_ID は、ウェブサイト用に作成したスコアベース キーに置き換えます。

評価の作成

execute() 関数によって生成されたトークンで、バックエンドからの reCAPTCHA クライアント ライブラリか REST API を使用して評価を作成します。

このドキュメントでは、REST API を使用して MFA の評価を作成する方法について説明します。 クライアント ライブラリを使用して評価を作成する方法については、ウェブサイトの評価を作成するをご覧ください。

評価を作成する前に、次の操作を行います。

  • reCAPTCHA に対する認証を設定します。

    選択する認証方式は、reCAPTCHA が設定されている環境によって異なります。次の表は、認証を設定するために、適切な認証方法とサポートされているインターフェースを選択する際に有用です。

    環境 インターフェース 認証方法
    Google Cloud
    • REST
    • クライアント ライブラリ
    関連付けられているサービス アカウントを使用します。
    オンプレミスまたは別のクラウド プロバイダ REST API キー または Workload Identity 連携を使用します。

    API キーを使用する場合は、API キー制限を適用して API キーを保護することをおすすめします。

    クライアント ライブラリ

    以下の対象を使用します。

  • ユーザーが頻繁に変更しない固定のアカウント ID accountId を選択し、 projects.assessments.create メソッドで評価を指定します。この固定アカウント ID は、同じユーザーに関連するすべてのイベントで同じ値にする必要があります。アカウント ID として、以下を指定できます。

    ユーザー識別子

    すべてのアカウントを、固定のユーザー名、メールアドレス、電話番号に一意に関連付けることができる場合は、accountId として使用できます。このようなクロスサイト ID(サイト間で再利用できる ID)を指定すると、reCAPTCHA はこの情報を使用して、不正なアカウント ID にフラグを立て、こうした識別子に関連するクロスサイト不正行為のパターンに関する知識を活用することで、クロスサイト モデルに基づいてユーザー アカウントの保護を強化します。

    あるいは、各アカウントに一意に関連付けられた内部ユーザー ID がある場合は、それを accountId として指定できます。

    ハッシュ化と暗号化

    各アカウントに一意に関連付けられた内部ユーザー ID がない場合は、安定した識別子を不透明なサイト固有のアカウント識別子にできます。この識別子は、reCAPTCHA のアカウント保護機能がユーザー アクティビティ パターンを把握して異常な動作を検出するために引き続き必要ですが、他のサイトと共有されることはありません。

    任意の固定アカウント ID を選び、暗号化またはハッシュ化を使用して、reCAPTCHA に送信する前に不透明化します。

    • 暗号化(推奨):安定した暗号テキストを生成する決定的な暗号化方法を使用して、アカウント ID を暗号化します。詳細な手順については、データを確定的に暗号化するをご覧ください。ハッシュ化ではなく対称暗号化を選択した場合、ユーザー ID と対応する不透明なユーザー ID とのマッピングを維持する必要はありません。reCAPTCHA から返される不透明な ID を復号して、ユーザー ID に変換します。

    • ハッシュ化: SHA256-HMAC メソッドを使用して、任意のカスタム ソルトでアカウント ID をハッシュ化することをおすすめします。ハッシュは一方向のため、生成されたハッシュとユーザー ID の間のマッピングを維持する必要があります。これにより、元のアカウントに返されるハッシュ化されたアカウント ID をマッピングできます。

accountId パラメータとエンドポイント(メールアドレスなど)を追加し、projects.assessments.create メソッドの評価で確認します。

リクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: Google Cloud プロジェクト ID。
  • TOKEN: grecaptcha.enterprise.execute() 呼び出しから返されたトークン。
  • KEY_ID: ウェブサイトにインストールしたスコアベース キー。
  • ACCOUNT_ID: ウェブサイトに固有のユーザー アカウントの ID。
  • EMAIL_ID: 確認リクエストをトリガーする必要があるメールアドレス。

HTTP メソッドと URL:

POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments

リクエストの本文(JSON):

{
  "event": {
    "token": "TOKEN",
    "siteKey": "KEY_ID",
    "userInfo": {
       "accountId": "ACCOUNT_ID"
    }
  }
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "EMAIL_ID",
    }]
  }
}

リクエストを送信するには、次のいずれかのオプションを選択します。

curl

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments"

PowerShell

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments" | Select-Object -Expand Content

次のような JSON レスポンスが返されます。


{
  [...],
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "foo@bar.com",
      "requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
      "lastVerificationTime": "",
    }],
    "latestVerificationResult": "RESULT_UNSPECIFIED"
  }
}

評価には、トークンを発行したデバイス(存在する場合)の特定のエンドポイントについて、確認が最後に成功した日時が記載されています。また、エンドポイントごとに 1 つの requestToken フィールドも存在します。このフィールドには暗号化された文字列が含まれます。そのエンドポイントで MFA チャレンジをトリガーする場合は、この暗号化された文字列をウェブページに送り返す必要があります。リクエスト トークンは 15 分間有効です。

プロジェクトで reCAPTCHA アカウント保護が有効になっている場合、評価レスポンスには、MFA に関連する情報に加えて、アカウント保護に関連する情報が含まれています。recommended_action フィールドには、MFA チャレンジをトリガーする前に実行できるアクションが表示されます。

次の例は、推奨されるアクションとして MFA をスキップするサンプル評価を示しています。

{
  [...],
  "accountDefenderAssessment": {
    labels: ["PROFILE_MATCH"],
    "recommended_action": "SKIP_2FA"
  }
}

recommended_action フィールドは次のいずれかの値になります。

説明
RECOMMENDED_ACTION_UNSPECIFIED アカウント防御がこのリクエストについて判断できなかったことを示します。
SKIP_2FA アカウント防御がこの評価の MFA をスキップしても安全であると判断したことを示します。これは通常、このデバイスのサイトに対してユーザーが最近確認されたことを意味します。
REQUEST_2FA ユーザーの MFA チャレンジをトリガーすることを示します。詳細については、アカウント防御の評価レスポンスをご覧ください。

ウェブサイトで MFA チャレンジをトリガーする

評価に含まれる情報に基づいてユーザーにチャレンジを行うには、検証するエンドポイントの MFA requestToken を評価からウェブページに戻します。

challengeAccount() を呼び出して MFA チャレンジをトリガーします。 challengeAccount() 関数は、チャレンジの完了後に解決される Promise、またはエラーやタイムアウトが発生した場合は拒否される Promise を返します。完了すると、更新された情報を含む新しいトークンが生成され、評価のために送信されます。

次の手順で MFA チャレンジをトリガーします。

  1. MFA 統合をテストします。

    次の値を指定して challengeAccount() を呼び出し、MFA チャレンジをトリガーします。

    • KEY_ID: ウェブサイトにインストールしたスコアベース キー。
    • REQUEST_TOKEN_FROM_ASSESSMENT: 評価レスポンスの requestToken フィールドの値。
    • CONTAINER_HTML_COMPONENT_ID: 確認チャレンジをレンダリングする必要がある HTML コンポーネントの ID。このパラメータを指定しない場合、チャレンジはページ上のオーバーレイにレンダリングされます。

    次の例では、challengeAccount() の呼び出しで MFA チャレンジをトリガーする方法を示します。

    grecaptcha.enterprise.challengeAccount(KEY_ID, {
      'account-token': REQUEST_TOKEN_FROM_ASSESSMENT,
      'container': CONTAINER_HTML_COMPONENT_ID
    }).then(newToken => {
      // Handle the new token.
    });
    

    challengeAccount() リクエストが成功すると、受信した PIN を入力するための HTML コンポーネントが表示されます。正しい PIN が入力されると、newToken 変数が、バックエンドで作成された評価を通じて検証される検証トークンを含むチェーン関数に渡されます。

  2. 検証ハンドルを作成し、次のパラメータを使用してチャレンジを開始します。

    // Initialize verification handle.
    const verificationHandle = grecaptcha.enterprise.eap.initTwoFactorVerificationHandle(
      KEY_ID,
      REQUEST_TOKEN_FROM_ASSESSMENT
    );
    
    // Call the challenge API.
    verificationHandle.challengeAccount().then(
      (challengeResponse) => {
        if (challengeResponse.isSuccess()) {
          // Handle success: This means displaying an input for the end user to
          // enter the PIN that they received and then call the `verifyAccount(pin)`
          // method.
        } else {
          // Handle API failure
        }
      });
    

ウェブページからの MFA コードを確認する

エンドユーザーから PIN を取得したら、PIN が正しいかどうかを検証する必要があります。

PIN を検証するには、エンドユーザーが入力した PIN を使用して verificationHandle.verifyAccount() を呼び出します。

verificationHandle.verifyAccount(pin).then(
  (verifyResponse) => {
    if (verifyResponse.isSuccess()) {
      // Handle success: Send the result of `verifyResponse.getVerdictToken()`
      // to the backend in order to determine if the code was valid.
    } else {
      // Handle API failure
    }
  },
  (error) => {
    // Handle other errors
  }
);

新しい評価を作成する

accountIdendpoints を使用して新しい評価を作成します。手順については、MFA の評価を作成するをご覧ください。

クライアントでワークフローが完了すると、新しいトークンが返されます。これを使用して、トリガーした確認の判定を取得できます。評価には、最新の成功した確認に関する最新のタイムスタンプと、成功結果のステータスが含まれます。

次の例は、クライアントから取得した新しいトークンを使用して新しい評価をリクエストした場合に受け取る、サンプル評価を示します。

{
  [...],
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "foo@bar.com",
      "requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
      "lastVerificationTime": "2020-03-23 08:27:12 PST",
    }],
    "latestVerificationResult": "SUCCESS_USER_VERIFIED"
  }
}

latestVerificationResult フィールドには、下の表のように異なるステータスが表示されます。

検証の結果のステータス 説明
SUCCESS_USER_VERIFIED ユーザーは正しく検証されました。
ERROR_USER_NOT_VERIFIED ユーザーの本人確認に失敗しました。
ERROR_SITE_ONBOARDING_INCOMPLETE サイトが正しく導入されていません。
ERROR_RECIPIENT_NOT_ALLOWED この受信者へのメールの送信は承認されていません(テスト中のみ)。
ERROR_RECIPIENT_ABUSE_LIMIT_EXHAUSTED この宛先は、短期間にあまりにも多くの確認コードを受け取っています。
ERROR_CUSTOMER_QUOTA_EXHAUSTED 利用可能な MFA の割り当てを超えました。
ERROR_CRITICAL_INTERNAL システムの内部エラーにより、確認が完了していません。
RESULT_UNSPECIFIED 最新の確認に関する情報はありません(未確認)。

次のステップ