- カスタムのプライバシーポリシーへの同意、利用規約、およびデータ開示フォーム。
- 追加で必要なプロフィールデータを一度だけ安全に収集すること。
- リモートの 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 にユーザーをリダイレクトして、新しいパスワードでサインインできるようにします。
データの保存先
セキュリティに関する考慮事項
UnauthorizedError を使って認可の試行を拒否する場合) に限って行うべきです。
一方、Auth0 に直接応答してアクセスを制限するための指示を返す必要がある場合 (CAPTCHA チェックやカスタム MFA を実装している場合) は、その処理に必要な要件が満たされたことを Auth0 に安全に伝える手段が必要です。同様に、リダイレクト先のアプリケーションに情報を渡す必要がある場合も、受け渡した情報が改ざんされていないことを安全に保証する方法が必要です。
アプリが同じユーザーにログインしていることを確認する
ルールに情報を返す
/continue エンドポイントへリダイレクトして戻す前に完了していれば、ユーザー情報は更新されます。ルール自体が情報を受け取る必要があり、かつその情報がそのサインインセッションにだけ関係する場合にのみ、情報をルールに返すべきです。
/continue エンドポイントに情報を返す際、渡すトークンは次の要件を満たしている必要があります。
送信には POST を使用し、クエリパラメータとして渡すのではなく、
context.request.body.token (または同様の場所) から取得するようにしてください。これは認証の form-post メソッドに似ています。
/continue エンドポイントに情報を返さない場合は、有効期限が十分に短く、リプレイ攻撃がほぼ不可能である場合を除き、JTI を denylist に追加することを検討してください。
制約と制限
context.protocol を確認することで判別できます。
- パスワード交換の場合:
context.protocol === 'oauth2-password' - 交換の場合:
context.protocol === 'oauth2-refresh-token' - ログインの場合:
context.protocol === 'oauth2-resource-owner'
セッションタイムアウト
Resource Owner エンドポイント
/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 を使用することはできません。
このケースでは、リフレッシュトークンの生成時にそれらのチャレンジが必須であれば、ユーザーがチャレンジを通過したことを確実に確認できるため、リフレッシュトークンのみを使用することを推奨します。