Adaptive MFAをカスタマイズする

Adaptive MFAは、Auth0 Actionsを使用してさまざまなシナリオでカスタマイズできます。

Adaptive MFAをカスタマイズするタイミング

ユーザーがMFAに登録されていない場合は、Adaptive MFAにデフォルトのポリシーを使用してください。ユーザーがMFAに登録されておらず、アクションが高リスクだと判断した場合、不正者を阻止する方法は限られてしまいます。

Adaptive MFAのカスタマイズを始める前に、ご自身で以下の点を検討してください。

  • どの信頼レベルでMFAをトリガーしたいか?

  • リスクをどのように測定したいか?

  • Auth0で信頼度を測定したいか、それともカスタム測定をしたいか?

  • MFAに登録していないユーザーをどのように処理するか?

信頼度を評価する

Adaptive MFAは、3つの評価分析に基づいて全体的な信頼スコアを計算します。評価ごとに独自の信頼スコアが設定されています。詳細については、「Adaptive MFA」をお読みください。

信頼スコア

信頼スコアと関連するアクションについては以下に説明します。

信頼度スコア 説明 アクション
low ログイントランザクションがユーザーによって前に表示されたパターンに一致しません。 MFAが必要です。
medium ログイントランザクションがユーザーによって前に表示されたパターンに多少一致します。 MFAは必要でありません。
high ログイントランザクションがユーザーによって前に表示されたパターンにぴったり一致します。 MFAは必要でありません。
neutral 非該当。今後使用するために予約されています。 非該当。今後使用するために予約されています。

カスタム信頼スコア

さまざまなシナリオの全体的な信頼スコアを評価するために独自のメソッドを実装したい場合は、riskAssessmentオブジェクトにあるデータを使用することができます。

以下の例をお読みいただき、Adaptive MFAがさまざまなユースケースの信頼スコアをどのように計算するか理解してください。

「リスクが高く、信頼度が低い」シナリオの例

下の表は、リスクが高いために信頼スコアがlow(低)になるシナリオを示しています。

ユーザーの状態 希望するログインフリクション 希望する登録ポリシー 実装
MFAに登録済み MFAを必要としない 非該当(ユーザーは登録済み) MFAをバイパスするようアクションを使用する
MFAに未登録 メール確認を必要とする 登録をスキップする(追加の鑑別工具を収集しない) デフォルトの動作(MFAに関連しないアクション)
MFAに未登録 メール確認を必要とする MFA登録を必要とする(追加の鑑別工具を収集する) アクションを使ってMFA登録を強制する(テンプレート利用可能)

「リスクが低く、信頼度が高い」シナリオの例

下の表は、リスクが低いために信頼スコアがhigh(高)になるシナリオを示しています。

ユーザーの状態 望ましいログイン時フリクション 必要な登録ポリシー 実装
MFAに登録済み フリクションなし 非該当(ユーザーは登録済み) デフォルトの動作(MFA関連のアクションなし)
MFAに未登録 フリクションなし 登録をスキップ(追加のAuthenticatorを収集しない) デフォルトの動作(MFA関連のアクションなし)
MFAに未登録 フリクションなし MFAの登録が必要(追加のAuthenticatorを収集する) アクションを使ってMFA登録を実施(テンプレート利用可能)

riskAssessmentオブジェクト

riskAssessmentオブジェクトには、全体的な信頼スコア、バージョン情報、および各評価の詳細が含まれています。

プロパティ 説明 タイプ 可能な値
confidence Adaptive MFAによって計算された全体の信頼度スコア。 文字列 lowmediumhighneutral
version リスク評価APIのバージョン識別子。 文字列 1
assessments 個々の評価詳細が含まれるオブジェクト。 オブジェクト 評価オブジェクト」を参照。

exports.onExecutePostLogin = async (event, api) => {
  if (event.authentication && event.authentication.riskAssessment) {
    event.authentication.riskAssessment = {
      confidence: 'low' | 'medium' | 'high' | 'neutral',
      version: '1',
      assessments: {
        UntrustedIP: {
          confidence: 'low' | 'medium' | 'high' | 'neutral',
          code: 'not_found_on_deny_list' | 'found_on_deny_list',
          details: { // only if 'found_on_deny_list'
            ip: '192.168.1.1',
            matches: '192.168.0/64',
            source: 'firehol',
            category: 'abuse'
          }
        },
        NewDevice: {
          confidence: 'low' | 'medium' | 'high' | 'neutral',
          code: 'match' | 'partial_match' | 'no_match',
          details: {
            device: 'known' | 'unknown',
            useragent: 'known' | 'unknown',
          }
        },
        ImpossibleTravel: {
          confidence: 'low' | 'medium' | 'high' | 'neutral',
          code: 'missing_geoip', | 'anonymous_proxy' | 'unknown_location' | 'initial_login' | 'location_history_not_found' | 'invalid_travel' | 'minimal_travel_from_last_login' | 'impossible_travel_from_last_login' | 'substantial_travel_from_last_login' | 'travel_from_last_login'
        } 
      },
       PhoneNumber: {
          code: "requires_verification | ok",
          confidence: "low | medium | high | neutral",
          details: {
	        	lineType: "FIXED_LINE | MOBILE | FIXED_LINE_OR_MOBILE | TOLL_FREE | PREMIUM_RATE | SHARED_COST | VOIP | PERSONAL_NUMBER | PAGER | UAN | UNKNOWN"
	            isValid: true | false,
		        countryCode: 1,
		        number: "+12223334444"
        }
      }
    };
  }
}

Was this helpful?

/

assessmentsオブジェクト

assessmentsオブジェクトには、3つの各リスク評価の詳細が含まれています。

  1. NewDevice評価

  2. ImpossibleTravel評価

  3. UntrustedIP評価

  4. PhoneNumber評価

各評価には信頼スコア、評価結果を説明するコード、およびその他のコンテキスト情報が含まれています。

NewDevice評価

NewDevice評価では、ユーザーが既知のデバイスからログインしているかどうかを判定し、以下のプロパティが含まれます。

プロパティ 説明 タイプ 使用可能な値
confidence Adaptive MFAが計算した信頼度スコア。 文字列 lowmediumhighneutral
code アセスメントの評価結果。 文字列 matchpartial_matchno_matchinitial_loginunknown_deviceno_device_historyassessment_not_available
details 追加のコンテキスト情報。 オブジェクト 以下の表を参照してください。

NewDevice評価コードのプロパティ

NewDevice評価codeプロパティは以下のいずれかの値に等しくなります。

説明
match detailsオブジェクトのプロパティ値が同等です。
partial_match detailsオブジェクトのプロパティ値が類似しています。
no_match detailsオブジェクトのプロパティ値が異なります。
initial_login ユーザーが初めてデバイスにログインしました。
unknown_device Auth0はデバイスのメタデータを見つけることができませんでした。
no_device_history デバイスに関連するログイン履歴がありません。
assessment_not_available Auth0はデバイスの評価を実行できませんでした。

NewDevice評価の詳細オブジェクト

codeプロパティの値がmatchpartial_match、またはno_matchに等しい場合、NewDevice評価には以下のプロパティを持つdetailsオブジェクトが含まれます。

プロパティ 説明 タイプ 可能な値
device ユーザーのデバイス。 文字列 knownunknown
useragent ユーザーのユーザーエージェント。 文字列 knownunknown

ImpossibleTravel評価

ImpossibleTravel評価では、ユーザーが不可能な移動を示す場所からログインしているかどうかを判定し、以下のプロパティが含まれます。

プロパティ 説明 タイプ 使用可能な値
confidence Adaptive MFAが計算した信頼度スコア。 文字列 lowmediumhighneutral
code アセスメントの評価結果。 文字列 minimal_travel_from_last_logintravel_from_last_loginsubstantial_travel_from_last_loginimpossible_travel_from_last_logininvalid_travelmissing_geoipanonymous_proxyunknown_locationinitial_loginlocation_history_not_foundassessment_not_available

UntrustedIP評価

UntrustedIP評価では、ユーザーのIPアドレスがレピュテーションが低いIPアドレス(「拒否リスト」)のAuth0のリポジトリに存在するかどうかを判定し、以下のプロパティが含まれます。

プロパティ 説明 タイプ 使用可能な値
confidence Adaptive MFAが計算した信頼度スコア。 文字列 lowmediumhighneutral
code アセスメントの評価結果。 文字列 not_found_on_deny_listfound_on_deny_listinvalid_ip_addressassessment_not_available
details 追加のコンテキスト情報。 オブジェクト 以下の表を参照してください。

UntrustedIP評価の詳細オブジェクト

UntrustedIP評価のcodeプロパティの値がfound_on_deny_listに等しい場合、detailsオブジェクトは存在し、以下のプロパティが含まれます。

プロパティ 説明 タイプ 取り得る値
ip デバイスのIPアドレス。 string 任意の有効なIPv4またはIPv6アドレス。
matches IPアドレスが属するサブネットマスク。 string 任意の有効なIPv4またはIPv6サブネットマスク。
source 拒否リストの脅威インテリジェンスソースの名前。 string 任意の有効なテキスト。
category IPアドレスが信頼されない理由を示したカテゴリ。 string abuseanonymizerdatacenterreputationunroutable

UntrustedIP評価の詳細オブジェクトカテゴリのプロパティ

UntrustedIP評価のdetailsオブジェクトcategoryのプロパティでは、Adaptive MFAが特定のIPアドレスを信用できないものとみなす一般的な理由を説明し、以下のいずれかの値に等しくなります。

説明
abuse IPアドレスの動作が不正か、ボットネットの一部だと判明しました。
anonymizer VPNプロバイダー、公開プロキシ、Tor Exitノードなど、匿名サービスのIPアドレスです。
datacenter クラウドホスティングサービスやコロケーションデータセンターのIPアドレスです。
reputation IPアドレスのアクティビティを基にした評判スコアが低いこをと示しています。
unroutable IPアドレスが、公認のインターネットレジストリーによって割り当てや委任された範囲内にないか、一般利用に許可されていません。

PhoneNumber評価

PhoneNumber評価では、送られてくるトランザクションに指定された電話番号のリスクを判定し、以下のプロパティが含まれます。

プロパティ 説明 タイプ 可能な値
code 評価結果の説明。 文字列 okrequires_verificationphone_number_not_providedassessment_not_available
confidence Adaptive MFAによって計算された信頼度スコア。 文字列 lowmediumhighneutral
details 追加のコンテキスト情報。 オブジェクト 下の表を参照。

PhoneNumber評価の詳細オブジェクト

PhoneNumber評価のdetailsオブジェクトには、以下のプロパティが含まれます。

プロパティ 説明 タイプ 使用可能な値
lineType 電話回線のタイプ 文字列 FIXED_LINEMOBILEFIXED_LINE_OR_MOBILETOLL_FREEPREMIUM_RATESHARED_COSTVOIPPERSONAL_NUMBERPAGERUANUNKNOWN
isValid 番号の有効性を返します ブール値 truefalse
countryCode 電話の発信元の国コード 整数 0-999
number 電話番号 文字列 有効な番号(countryCodeを含む)

アクションの結果

いずれかのアクションが信頼スコアに基づいてMFAをトリガーする場合、デフォルトのAdaptive MFAポリシーは、信頼スコアがlow(低)のときにMFAをトリガーします。

下の表は、アクションとデフォルトのAdaptive MFAポリシーアクションの組み合わせに基づいて考えられる結果を示しています。

アクションの結果 Adaptive MFAアクション 結果
未承認 MFAをトリガー 未承認
未承認 MFA不要 未承認
MFAをトリガー MFAをトリガー MFAをトリガー
MFAをトリガー MFA不要 MFAをトリガー
MFA不要 MFAをトリガー MFAをトリガー
MFA不要 MFA不要 MFA不要

Actionテンプレート

Auth0には、Adaptive MFAに基づいて、Adaptive MFARequire MFA Enrollment(MFA登録を必須にする)という2つのカスタマイズ可能なテンプレートが用意されています。

Adaptive MFAテンプレート

このテンプレートは例として、個々のリスク評価を使ってカスタムビジネスフローを構築する方法の始点を提供します。

/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
  if (event.authentication && 
      event.authentication.riskAssessment && 
      event.authentication.riskAssessment.assessments.NewDevice) {

  // Example condition: prompt MFA only based on the NewDevice 
    // confidence level, this will prompt for MFA when a user is logging in 
    // from an unknown device.
    let shouldPromptMfa;

    switch (event.authentication.riskAssessment.assessments.NewDevice.confidence) {
      case 'low':
      case 'medium':
        shouldPromptMfa = true;
        break;
      case 'high':
        shouldPromptMfa = false;
        break;
      case 'neutral':
        // When this assessor has no useful information about the confidence, 
        // do not prompt MFA.
        shouldPromptMfa = false;
        break;
    }

      // It only makes sense to prompt for MFA when the user has at least one 
      // enrolled MFA factor.
    const canPromptMfa = event.user.multifactor && event.user.multifactor.length > 0;

    if (shouldPromptMfa && canPromptMfa) {
      api.multifactor.enable('any', { allowRememberBrowser: true });
    }
  }
};

Was this helpful?

/

Require MFA Enrollmentテンプレート

このテンプレートは、標準またはAdaptive MFAポリシーを使うときに、MFA登録をどのように強制できるかを示しています。ここでは、event.user.multifactorを使ってユーザーがMFAに登録しているかどうかを確認し、登録していない場合は、登録するよう促します。

/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
  if (!event.user.multifactor || event.user.multifactor.length == 0) {
    api.multifactor.enable('any', { allowRememberBrowser: true });
  }
};

Was this helpful?

/

Actionのユースケース

ユースケースに基づいてカスタムアクションを構築する方法に関する提案をご紹介します。

全体的な信頼スコアがXの場合にアクションを実行する

riskAssessment.confidenceプロパティを評価してから、highmedium、またはlowといった定数と比較します。

exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication || {};
  const riskIsMedium = riskAssessment && riskAssessment.confidence === 'medium';

  if (riskIsMedium) {
    // ....
  }
}

Was this helpful?

/

信頼スコアがX以上またはX以下である場合にアクションを実行する

信頼スコアは範囲でなく不連続の値です。そのため、比較演算子(<>など)を使って複数の値を1つの状況で評価することはできません。

複数の状況を使って、処理したいすべての信頼スコアを論理的に組み合わせます。たとえば、信頼スコアがlowより大きいかどうかを知りたい場合は、mediumまたはhighに等しいかどうかを確認します。

exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication || {};
  const riskIsMediumOrHigh = riskAssessment && 
                                  (riskAssessment.confidence === 'high' || 
                                   riskAssessment.confidence === 'medium');

  if (riskIsMediumOrHigh) {
    // ...
  }
}

Was this helpful?

/

全体的な信頼スコアがXの場合に追加の詳細を取得する

riskAssessmentオブジェクトはテナントログに保存されています。ログエントリーを表示し、リスク評価スコアと決定的な要因(理由)を確認します。

riskAssessmentオブジェクトを表示し、結果を別の場所で報告します。たとえば、メールを送信したり、レコードを外部データベースに保存したりできます。

exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication || {};
  const riskIsLow = riskAssessment && riskAssessment.confidence === 'low';

  if (riskIsLow) {
    // log(externalDatabase, riskAssessment);
  }
}

Was this helpful?

/

特定の評価に特定の結果が含まれている場合にアクションを実行する

assessmentsオブジェクト(codeプロパティなど)を使って各評価の詳細にアクセスします。

exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication || {};
  const { ImpossibleTravel } = riskAssessment && riskAssessment.assessments;

  if (ImpossibleTravel.code === 'impossible_travel_from_last_login') {
    // ...
  }
}

Was this helpful?

/

カスタムの全体的な信頼スコアの評価を集約する

assessmentsオブジェクトを使って各評価の詳細にアクセスしてから、confidenceプロパティ、codeプロパティ、またはその両方を使用します。

カスタム信頼スコアの詳細については、「カスタム信頼スコア」をお読みください。

特定の評価に特定の結果が含まれている場合は、現在のトランザクションをブロックし、エラーとメッセージを返します。

assessmentsオブジェクト(codeプロパティなど)を使って各評価の詳細にアクセスします。

UnauthorizedErrorオブジェクトをエラーパラメーターに使用してコールバック関数を返すことで、ログイントランザクションが完了するのブロックします。UnauthorizedErrorオブジェクトは必ずerrorunauthorizedに設定しますが、error_messageをカスタマイズすることはできます。

exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication || {};
  const { ImpossibleTravel } = riskAssessment && riskAssessment.assessments;

  if (ImpossibleTravel.code === 'impossible_travel_from_last_login') {
    return api.access.deny('Login blocked due to impossible travel detected.')
  }
}

Was this helpful?

/

これによってユーザーは、errorおよびerror_messageパラメーターを含んだアプリケーションのコールバックURLにリダイレクトされます。

Auth0が評価を実行できない場合に安全に処理する

リスク評価の実行時に何かしらのエラーが発生した場合、Auth0は自動的にlow信頼レベルを割り当てます。

このシナリオを軽減するには、assessmentsオブジェクトを使って個々の評価のcodeプロパティを点検し、値がassessment_not_availableに設定されているかどうかを確認します。

もっと詳しく