- カスタムのプライバシーポリシーへの同意、利用規約、およびデータ開示フォーム。
- 追加で必要なユーザープロファイルデータを一度だけ安全に収集すること。
- リモートの Active Directory ユーザーがパスワードを変更できるようにすること。
- 不明な場所からログインした場合に、ユーザーに追加の確認を求めること。
- 初回サインアップ時に提供された情報に加えて、ユーザーに関する詳しい情報を収集すること。
リダイレクトを開始し、認証を再開する
context.redirect プロパティを次のように設定します。
context.redirect.urlプロパティで指定されたURLにリダイレクトします。また、そのURLにはstateパラメーターも渡されます。例:
state パラメーターを抽出し、認証トランザクションを再開するために Auth0 に送り返す必要があります。state は不透明な値であり、クロスサイト・リクエスト・フォージェリ (CSRF) 攻撃 を防ぐために使用されます。
リダイレクト後は、ユーザーを /continue エンドポイントにリダイレクトし、受け取った state パラメーターを URL に含めて認証を再開します。元の state を /continue エンドポイントに送り返さないと、Auth0 はログイントランザクションのコンテキストを失い、ユーザーは invalid_request エラーによりログインできなくなります。
例:
を使用している場合:
THE_ORIGINAL_STATE は、Auth0 が生成し、リダイレクト URL に付与して送信した値です。たとえば、Rule が https://example.com/foo にリダイレクトした場合、Auth0 は https://example.com/foo?state=abc123 のようなリダイレクト URL を使用します。つまり、abc123 が THE_ORIGINAL_STATE です。認証トランザクションを再開するには、次の URL にリダイレクトします。
ユーザーが /continue エンドポイントにリダイレクトされた場合:
- すべての Rules が再度実行されます。ただし、認証を続行できるよう、
context.redirectは無視されます。 - ユーザーオブジェクトへの変更は、
/continueエンドポイントを呼び出す前のリダイレクト中に行われます。たとえば、Auth0 の を介した更新は、トランザクションの続行後に反映されます。
再開されたログインを検証する
context.protocol プロパティを確認します。
パスワード変更を強制する例
- ユーザーがログインを試みますが、パスワードを変更する必要があります。
- ユーザーは、クエリ文字列に JWT を含むアプリケーション固有のページへリダイレクトされます。この JWT は、そのユーザー自身のパスワードのみを変更できることを保証するものであり、アプリケーションで必ず検証する必要があります。
- ユーザーは、アプリケーションが Auth0 Management API を呼び出すことで、アプリケーション固有のページ上でパスワードを変更します。
- ユーザーがパスワードの変更に成功したら、アプリケーションは検証およびデコード済みの JWT から
authorize_againクレームを取得し、その URL にユーザーをリダイレクトして、新しいパスワードでサインインできるようにします。
データの保存場所
セキュリティに関する考慮事項
UnauthorizedError で認可の試行を拒否する場合) に限るべきです。
一方で、Auth0 に直接情報を返し、アクセス制限のための指示を与える必要がある場合 (キャプチャのチェックやカスタム MFA を実装している場合) は、その処理に必要な要件が満たされたことを Auth0 に安全に伝える手段が必要です。同様に、リダイレクト先のアプリケーションに情報を渡す必要がある場合も、転送される情報が改ざんされていないことを安全に保証できる手段が必要です。
アプリが同じユーザーにログインしていることを確認する
Rule に情報を返す
/continue エンドポイントへリダイレクトして戻す前に完了していれば、ユーザー情報は更新されます。Rule 自体がその情報を必要としており、かつその情報がそのサインインセッションにのみ関連する場合に限って、情報を Rule に返すようにしてください。
/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'
セッションのタイムアウト
リソースオーナー エンドポイント
/oauth/token を直接呼び出す場合、リダイレクト Rule は使用できません。ユーザーはもともとリダイレクト フローにいないため、Rule でユーザーをリダイレクトすることはできません。context.redirect を設定しようとすると、ログインは失敗し、interaction_required エラーが返されます。
prompt=none を使用するフロー
prompt=none の目的は、ユーザーの入力が必要になる状況を一切発生させないことにあるため、リダイレクトが発生すると error=interaction_required になります。
Rules は認証セッションの作成後に実行されるため、特定の条件下でトークンへのアクセスをブロックしようとするリダイレクト Rule (カスタム MFA、ログイン時のキャプチャ など) がある場合は、prompt=none を使用できません。
トークンへのアクセスをブロックするリダイレクトフローを作成しつつ、prompt=none の場合にはそのリダイレクト Rule を回避させないようにすることはできません。最初の試行で Rules が失敗しても認証セッション自体は作成されるため、失敗後にユーザーが prompt=none を付けて再度呼び出すだけで、トークンを取得できてしまうからです。
リフレッシュトークン
/oauth/token へのバックチャネル呼び出しが必要なため、context.redirect を設定すると、これも失敗します。
ログインに対する制限が実際に適用されたことを安全に検証するのは困難です。コンテキスト内には一貫したセッション ID がなく、このユーザーが MFA チャレンジを通過したかどうかといった、セッションに関連する情報を収集するために利用できません。そのため、prompt=none はまったく使用できません。
Rule で context.redirect が設定されていて、prompt=none が渡されている場合、認可は error=interaction_required で失敗します。しかし、Rules が失敗してもユーザーのセッション自体は作成されるため、ユーザーが context.redirect のすべてのチャレンジを通過したと信頼することはできません。したがって、トークンを取得する手段として prompt=none は使用できません。
このケースでは、リフレッシュトークンのみを使用することをお勧めします。リフレッシュトークンの発行にそれらのチャレンジが必要であれば、ユーザーがチャレンジを通過したことを確実に確認できるためです。