- カスタムのプライバシーポリシーへの同意、利用規約、データ開示のフォームを使用できるようにする
- 追加で必要なプロファイルデータを安全に一度だけ収集する
- Microsoft Entra IDのリモートユーザーがパスワードを変更できるようにする
- ユーザーが未知の場所からログインする際に、追加で検証を求める
- サインアップ時にユーザーが提供したよりも多くのユーザー情報を集める
概要
リダイレクトのアクションは通常、以下のように動作します。- アクションがURLへリダイレクトを送信します。
- そのアクションの実行が完了すると、Actionsパイプラインが中断されます。
- ユーザーが
state
パラメーターとURLともににリダイレクトされます。 - 外部フローが終了すると、外部サイトが
state
パラメーターとともにユーザーを/continue
エンドポイントにリダイレクトします。 - リダイレクトを行った同じアクションからActionsパイプラインが再開します。
リダイレクトを開始する
以下のようにapi.redirect.sendUserTo()
機能を呼び出します。
https://my-app.exampleco.com
に送信します。つまり、このリダイレクトを行ったアクションの後にログイン後トリガーが実行される場合、そのログイン後トリガーにバインドされているアクションはすべて、認証フローが再開するまで実行されないことになります。リダイレクトのルールに慣れているのであれば、リダイレクトのアクションとリダイレクトのルールがこの点で大きく違うことに注意してください。
リダイレクトアクションは、リダイレクトルールとは異なり、リダイレクトが発行された時点でActionsパイプラインを中断します。認証フローが続行された場合は、リダイレクトを発行したアクションでパイプラインを再開します。
api.redirect.sendUserTo()
関数でURL指定された場所にリダイレクトします。Auth0はそのURLにstate
パラメーターも渡します。例:
https://my-app.exampleco.com/?state=abc123
リダイレクトURLはstate
パラメーターを抽出し、それをAuth0に送り返して認証トランザクションを再開する必要があります。状態は不透明な値で、クロスサイトリクエストフォージェリ(CSRF)攻撃を防ぐために使用されます。
認証フローを再開する
リダイレクト後にユーザーを/continue
エンドポイントにリダイレクトし、URLで受信したstate
パラメーターを含めることで認証を再開します。元の状態を/continue
エンドポイントに送り返さないと、Auth0はログイントランザクションのコンテキストを失い、invalid_request
エラーのためにユーザーがログインできなくなります。
例:
https://{yourAuth0Domain}/continue?state=THE_ORIGINAL_STATE
この例では、THE_ORIGINAL_STATE
はAuth0が生成し、リダイレクトURLに送信した値です。たとえば、アクションがhttps://my-app.exampleco.com/
にリダイレクトすると、Auth0はhttps://my-app.exampleco.com/?state=abc123
と同様にリダイレクトURLを使用し、abc123
をTHE_ORIGINAL_STATE
にします。認証トランザクションを再開するには、以下にリダイレクトします。
https://{yourAuth0Domain}/continue?state=abc123
ユーザーが/continue
エンドポイントにリダイレクトされると、ActionsパイプラインがonContinuePostLogin
関数を呼び出して、リダイレクトの呼び出しと同じアクションで再開します。リダイレクトが正しく動作するには、リダイレクトを行った同じアクションに以下の署名を含む関数が必要です。
データを外部のサイトへ渡す
データを外部サイトに渡す場合は、そのデータを署名済みのJWTでエンコードすることをお勧めします。そうすれば、アプリケーションは送信中にデータが改ざんされていないことを確信できます。Actionsではapi.redirect.encodeToken
およびapi.redirect.sendUserTo
関数を使用してこれを実行できます。
session_token
クエリ文字列パラメーターを(Auth0が自動的に追加するstate
パラメーターに加えて)追加します。このトークンには以下が含まれます。
トークンの要素 | 説明 |
---|---|
sub | ユーザーのAuth0のuser_id です。 |
iss | Auth0テナントドメインのホスト名(example.auth0.com など)です。 |
exp | expiresInSeconds パラメーターで指定される秒単位の有効期限です。トークンが再利用されないように、できるだけ短くします。デフォルトは900秒(15分)です。 |
ip | 認証要求元のIPアドレスです。 |
email | payload.email パラメーターで値が指定されているカスタムクレームです。 |
externalUserId | payload.externalUserId パラメーターで値が指定されているカスタムクレームです。 |
signature | トークンは、上記で指定のシークレットを使用して、HS256アルゴリズムで署名されます。 |
トークンが改ざんされていないことを確認する
外部のシステムは、このトークンが送信中に改ざんされていないことを検証しなければなりません。これを実現するために、リモートシステムはトークンの署名が有効であることを確認し、該当する場合は、外部システム内のセッションがトークンのsub
クレームで渡される同じAuth0ユーザーに属していることを確認しなければなりません。
データをAuth0へ戻す
ユーザーが外部サイトでカスタムフローを完了すると、/continue
エンドポイントにリダイレクトされます。状況によっては、データをAuth0に戻して、そのユーザーの認証フローや認可フロー(たとえば、CAPTCHA認証やカスタムなど)に影響を与える必要があるかもしれません。
できるだけアプリのメタデータを使用する
可能であれば、リモートシステムはAuth0 Management APIを使用して、カスタム情報をAuth0ユーザープロファイルのアプリケーションメタデータとして保管する必要があります。Auth0アクションフローが再開されると、この情報はevent.user.app_metadata
オブジェクトで利用できるようになります。この方法では、機密情報をフロントチャネルでAuth0に渡す必要がなくなります。
Auth0のユーザープロファイルにはデータを選択して保管する
Auth0のプロファイルに保管するデータは多すぎないようにします。このデータは認証および認可の目的で使用されるものです。Auth0のメタデータや検索機能は、マーケティング調査などのように、頻繁に検索や更新されることを想定して設計されたものではありません。Auth0をそのような目的で使用すると、ほぼ確実にシステムの拡張性や性能に問題が生じます。 アプリケーションにかなりの量のユーザーデータが必要な場合には、データを外部システムに保管して、Auth0に外部キー(ユーザーID)を保管すると、バックエンドシステムが必要に応じてデータを取得できるようになります。データをフロントチャネルに送信する
情報をフロントチャネルでやり取りすると、悪意のある行為者の攻撃対象になる領域を広げることになります。情報をフロントチャネルに送信しなければならない場合には、以下のガイダンスを考慮してください。情報をアクションへ戻す
機密情報をAuth0に送信して戻すには、必ず署名済みのセッショントークンを使用します。このトークンは、アクション内で以下のコードを使って手軽に検証することができます。- 署名が有効である
- トークンの有効期限が切れていない
- トークン内の
state
クレームは、リダイレクトの一部として使用されるstate
パラメーターと一致します。
トークンの要素 | 説明 |
---|---|
sub | ユーザーのAuth0のuser_id です。 |
iss | リダイレクト対象のアプリケーションです。 |
exp | トークンが再利用されないように、できるだけ短くします。 |
state | リダイレクトの一部としてリモートサイトに送信される状態パラメーターです。リプレイ攻撃を防ぐために、トークンに含まれる必要があります。 |
other | 上のコードでpayload として公開されるその他すべてのカスタムクレームです。 |
signature | トークンはHS256アルゴリズムで署名されなければなりません。 |
/continue
エンドポイントにPOST要求を行って、トークンをAuth0に送り返す必要があります。コード内のtokenParameterName
オプションを使用すると、トークンを含むフィールドの名前を指定できます。
カスタム認証方式
ログインパイプラインでリダイレクトに成功したら、アクションはカスタム認証方法のイベントをユーザーセッションに記録することができます。event.authentication.methods
配列には、ユーザーのブラウザーセッションが継続する間、カスタム認証方法のエントリが含まれます。この配列の各エントリーには、認証方法が記録された日時を示すタイムスタンプがあります。
必要なカスタム認証方法がevent.authentication.methods
配列にない場合、またはエントリが古すぎる場合には、カスタムアクションによってリダイレクトがトリガーされることがあります。
api.redirect.sendUserTo()
を使用して、カスタム認証方法を実装するページにユーザーを送信できます。exports.onContinuePostLogin
ハンドラーでapi.authentication.recordMethod()
を使用して、完了した認証方法の記録をユーザーのセッションに保管できます。
event.authentication.methods
配列に保管されるレコードには、api.authentication.recordMethod()
で選択されたURLと一致するname
プロパティが含まれます。ここでキャプチャされたURLによって、現在のトランザクションで完了された認証方法を検索し、カスタム認証方法がすでに完了されているかを判断できます。
ワークフローで、ユーザーセッションの有効期間中にカスタム認証方法の定期的な再実行が必要になるかもしれません。たとえば、カスタムMFAの使用では、指定された時間が経過すると、ユーザーの再検証が必要になることがあります。
以下の例では、カスタム認証方法を返す契機を決めるために、既存のレコードのタイムスタンプを照合します。
api.authentication.recordMethod()
APIは、exports.onContinuePostLogin
ハンドラーでのみ使用できます。リダイレクトの完了後にカスタム認証方法が記録されるため、ログインが悪用される可能性が軽減されます。
制約と制限
リダイレクトのアクションは以下では動作しません。リソース所有者のエンドポイント
リソース所有者パスワードフローでAuthentication APIのトークン取得エンドポイントを呼び出す場合、リダイレクトアクションは使用できません。そもそもユーザーがリダイレクトフローにいないため、アクションでリダイレクトできるユーザーもいません。prompt=noneのフロー
prompt=none
の目的は、ユーザーに入力を求めるシナリオを回避することであるため、リダイレクトするとerror=interaction_required
が発生します。
アクションは認証セッションの作成後に実行されるため、特定の条件下でトークンへのアクセスをブロックしようとするリダイレクトルールがある場合(カスタムMFA、ログイン時のCAPTCHAなど)、prompt=none
は使用できません。
prompt=none
の場合、トークンアクセスをブロックしてリダイレクトアクションをバイパスするリダイレクトフローを作成することはできません。これは、アクションが最初に失敗した場合でも認証セッションが作成されているため、試行が失敗した後、ユーザーがprompt=none
で再度呼び出してトークンを取得できるためです。
リフレッシュトークン
リフレッシュトークンを使用するには、Authentication APIのトークン取得エンドポイントへのバックチャネル呼び出しが必要であるため、リダイレクトしようとするとこれも失敗します。 ログインに関するどのような制約も、適用されたかを安全に検証することは困難です。MFAチャレンジに成功したユーザーなど、セッションに関する情報を集めるのに使用可能なコンテキストでは、恒常的なセッションIDはありません。したがって、prompt=none
を使用できません。
アクションでapi.redirect.sendUserTo()
が呼び出されるときに、prompt=none
が渡された場合、error=interaction_required
で認可が失敗しますが、アクションが失敗してもユーザーのセッションが作成されるため、ユーザーがリダイレクトチャレンジに合格したことを信頼できず、トークンを取得する方法としてprompt=none
を使用することはできません。
この特有なケースには、リフレッシュトークンの排他的な使用をお勧めします。リフレッシュトークンの生成にチャレンジが必要な場合に、ユーザーがチャレンジに成功したことを確認できるからです。