- カスタムのプライバシーポリシーへの同意、利用規約、およびデータ開示フォーム。
- 追加で必要なプロフィールデータを一度だけ安全に収集すること。
- リモートの Active Directory ユーザーがパスワードを変更できるようにすること。
- 不明な場所からログインした場合に、追加の確認をユーザーに求めること。
- 初回登録時に提供された情報に加えて、ユーザーに関する情報をさらに収集すること。
リダイレクトを開始し、認証を再開する
context.redirect プロパティを次のように設定します。
context.redirect.url プロパティで指定された URL にユーザーをリダイレクトします。さらに、Auth0 はその URL に state パラメータも付与します。例:
state パラメーターを取得し、認証トランザクションを再開するために Auth0 に返送する必要があります。state は不透明な値で、クロスサイト・リクエスト・フォージェリ (CSRF) 攻撃を防ぐために使用されます。
リダイレクト後は、ユーザーを /continue エンドポイントにリダイレクトし、受け取った state パラメーターを URL に含めて認証を再開します。元の state を /continue エンドポイントに返送しないと、Auth0 はログイントランザクションのコンテキストを失い、ユーザーは invalid_request エラーによりログインできなくなります。
たとえば、次のようになります。
を使用している場合:
THE_ORIGINAL_STATE は、Auth0 が生成し、リダイレクト URL に送信した値です。たとえば、ルールで https://example.com/foo にリダイレクトした場合、Auth0 は https://example.com/foo?state=abc123 のようなリダイレクト URL を使用します。つまり、abc123 が THE_ORIGINAL_STATE です。認証トランザクションを再開するには、次の URL にリダイレクトします。
ユーザーが/continueエンドポイントにリダイレクトされた場合:
- すべてのルールが再度実行されます。ただし、認証を続行できるよう、
context.redirectは無視されます。 - ユーザーオブジェクトへの変更は、
/continueエンドポイントを呼び出す前のリダイレクト中に行われます。たとえば、Auth0 を通じて行った更新は、トランザクションの続行後に反映されます。
再開されたログインの確認
ユーザーが開始したログインと再開されたログインフローを区別するには、context.protocol プロパティを確認してください。
パスワード変更を強制する例
特定の条件下では、ユーザーにパスワードの変更を必須にしたい場合があります。その場合は、次のように動作するルールを作成できます。- ユーザーがログインを試みますが、パスワードを変更する必要があります。
- ユーザーは、クエリ文字列に JWT が付与されたアプリケーション固有のページへリダイレクトされます。この JWT によって、このユーザーのパスワードだけを変更できることが保証されます。また、この JWT はアプリケーション側で必ず検証する必要があります。
- ユーザーは、アプリケーション固有のページでパスワードを変更します。このとき、アプリケーションは Auth0 Management API を呼び出します。
- ユーザーが正常にパスワードを変更したら、アプリケーションは検証済みかつデコード済みの JWT から
authorize_againclaim を取り出し、その URL にユーザーをリダイレクトして、新しいパスワードでサインインできるようにします。
データの保存先
Auth0 のプロファイルに過剰なデータを保存しないよう注意してください。これらのデータは、認証と認可のために使用することを想定しています。Auth0 のメタデータ機能や検索機能は、マーケティング調査や、検索や更新が高頻度で発生するその他の用途向けには設計されていません。この目的で Auth0 を使用すると、システムのスケーラビリティやパフォーマンスに問題が生じる可能性があります。より適切な方法は、データは外部システムに保存し、必要に応じてバックエンドシステムがそのデータを取得できるよう、Auth0 には参照先 (ユーザー ID) のみを保存することです。シンプルなルールとして、保存するのは、トークンに追加したり、意思決定に使ったりするためにルールで使用する予定のある項目だけにしてください。セキュリティに関する考慮事項
フロントチャネルで情報をやり取りすると、による攻撃対象領域が広がります。これは、ルール内で何らかの対応が必要な場合 (たとえば、UnauthorizedError を使って認可の試行を拒否する場合) に限って行うべきです。
一方、Auth0 に直接応答してアクセスを制限するための指示を返す必要がある場合 (CAPTCHA チェックやカスタム MFA を実装している場合) は、その処理に必要な要件が満たされたことを Auth0 に安全に伝える手段が必要です。同様に、リダイレクト先のアプリケーションに情報を渡す必要がある場合も、受け渡した情報が改ざんされていないことを安全に保証する方法が必要です。
アプリが同じユーザーにログインしていることを確認する
アプリケーションはユーザーを Auth0 テナントにリダイレクトして戻すため、ユーザーに関するあらゆるデータは、アプリケーションに返されるを通じて取得できます。ただし、途中で何らかの改ざんが行われていないことを確認するために、アプリケーションがリダイレクト元と同じユーザーにログインしていることを確認したい場合があります。そのため、通常はリクエストとあわせてトークンも送信することになります。 アプリに送信するトークンは、次の要件を満たす必要があります。ルールに情報を返す
ほとんどの場合、ルールからアプリケーションに情報を渡したい場合でも、その情報は必要に応じてアプリケーション側で安全に保存できるはずです。たとえば Auth0 のアプリメタデータやユーザーメタデータを更新したい場合でも、Management API を使って実行できます。ユーザーを/continue エンドポイントへリダイレクトして戻す前に完了していれば、ユーザー情報は更新されます。ルール自体が情報を受け取る必要があり、かつその情報がそのサインインセッションにだけ関係する場合にのみ、情報をルールに返すべきです。
/continue エンドポイントに情報を返す際、渡すトークンは次の要件を満たしている必要があります。
送信には POST を使用し、クエリパラメータとして渡すのではなく、
context.request.body.token (または同様の場所) から取得するようにしてください。これは認証の form-post メソッドに似ています。
/continue エンドポイントに情報を返さない場合は、有効期限が十分に短く、リプレイ攻撃がほぼ不可能である場合を除き、JTI を denylist に追加することを検討してください。
制約と制限
Redirect Rules は、以下では機能しません。 上記のケースは、context.protocol を確認することで判別できます。
- パスワード交換の場合:
context.protocol === 'oauth2-password' - 交換の場合:
context.protocol === 'oauth2-refresh-token' - ログインの場合:
context.protocol === 'oauth2-resource-owner'
セッションタイムアウト
リダイレクトルールのセッションは通常 3 日間有効です。ただし、Login Session Management の設定でそれより短いタイムアウトを設定している場合は、この限りではありません。これらの設定は、テナントの詳細設定 で確認できます。Resource Owner エンドポイント
Resource Owner Password Grant で/oauth/token を直接呼び出す場合、リダイレクトルールは使用できません。そもそもユーザーはリダイレクトフローに入っていないため、ルール内でユーザーをリダイレクトすることはできません。context.redirect を設定しようとすると、interaction_required エラーでログイン試行が失敗します。
prompt=none を使用するフロー
prompt=none の目的は、ユーザーに入力を求める必要がある状況を一切発生させないことにあるため、どのようなリダイレクトでも error=interaction_required が返されます。
ルールは認証セッションが作成された後に実行されるため、特定の条件下でトークンへのアクセスをブロックしようとするリダイレクトルール (カスタム MFA、ログイン時の CAPTCHA など) がある場合は、prompt=none を使用できません。
また、トークンへのアクセスをブロックするリダイレクトフローを作成しても、prompt=none の場合にリダイレクトルールを回避できないようにすることはできません。失敗した後でも、ユーザーは再度 prompt=none を付けて呼び出すだけでトークンを取得できてしまうためです。これは、最初の時点でルールが失敗していても、認証セッション自体はすでに作成されているからです。
リフレッシュトークン
リフレッシュトークンの使用には/oauth/token へのバックチャネル呼び出しが必要なため、context.redirect を設定すると、これも失敗します。
ログインに関する制限が実際に適用されたことを安全に検証するのは困難です。context には一貫したセッション ID が存在しないため、「このユーザーは MFA チャレンジを通過した」といったセッション関連の情報を収集する用途には使えません。したがって、prompt=none はまったく使用できません。
ルールで context.redirect が設定されている場合に prompt=none が渡されると、認可は error=interaction_required で失敗します。しかし、ルールが失敗してもユーザーのセッション自体は作成されるため、ユーザーがすべての context.redirect チャレンジを通過したと信頼することはできません。そのため、トークン取得の手段として prompt=none を使用することはできません。
このケースでは、リフレッシュトークンの生成時にそれらのチャレンジが必須であれば、ユーザーがチャレンジを通過したことを確実に確認できるため、リフレッシュトークンのみを使用することを推奨します。