OIDC ログインが Discourse iOS アプリ経由でコールバック時に csrf_detected で失敗することが時々ある からの議論の続きです。
皆さん、こんにちは。
これは、アプリ内ブラウザからの OIDC ログイン失敗に関する以前のスレッドに関連する、その後の観察結果です。その議論では、WKWebView の Cookie 分離によって引き起こされる決定的な csrf_detected 失敗に焦点が当てられており、それらは現在、よく理解され、予期されるものとなっています。
この関連トピックは、バグではなく、オペレーターの明確さに関するものです。
観察
一連の OIDC ログイン失敗を調査していると、Discourse における同じ表面的なエラー:
/auth/oidc/callback → /auth/failure?message=csrf_detected
が、IdP(IDプロバイダー)が返したものに応じて、根本的に異なる複数のアップストリームの原因に対応する場合があることに気づきました。
アプリケーション UI だけでは、これらのケースは区別できません。違いは、管理者 → ログ → env / params を調べることでのみ確認できます。
実際に見られた例(Azure / Entra ID)
アプリ内ブラウザでの Cookie 損失に加えて、Entra ID が構造化されたエラーを明示的に返すコールバックも確認されています。例えば次のとおりです。
ユーザーが同意を拒否した場合
error=consent_required
error_description=AADSTS65004: User declined to consent to access the app
ユーザーがログインをキャンセルした場合
error=access_denied
error_subcode=cancel
どちらのケースでも:
- Azure はユーザーを正常に識別しました
- ユーザーは明示的に続行しないことを選択しました(拒否 / キャンセル)
- Discourse はコールバックを受け取ります
- フローは最終的に
/auth/failure?message=csrf_detectedに解決します
Discourse の観点からは、これは正しく安全な動作です(状態を検証または完了できないため)が、根本的な理由は欠落しているセッション Cookie の場合とは大きく異なります。
オペレーターにとって重要な理由
ログの env/params を確認しない場合、繰り返される csrf_detected 失敗を目にした管理者は、次のように合理的に推測する可能性があります。
- Cookie の破損
- SameSite の設定ミス
- モバイルブラウザの問題
- IdP の不安定性
…しかし、実際には、それらの失敗の一部は、単にユーザーが同意しない、または Microsoft のプロンプトをキャンセルしたことによるものです。
この区別は、すでに生のログペイロードを調べる必要があることを知っている場合にのみ明らかになります。
提案(ドキュメント / UX のみに限る)
OmniAuth または CSRF 処理の動作変更を提案するものではありません。
ドキュメントまたはトラブルシューティングガイドで、次の点が明示的に記載されていると役立つかもしれません。
csrf_detectedは、複数のアップストリーム IdP の結果に対する最終的なエラーになり得る- それには、キャンセルや同意の拒否といった明示的なユーザーアクションが含まれる
- 管理者は、これらのケースを区別するために管理者 → ログ → env / params を確認する必要がある
これにより、オペレーターは次のことが容易になります。
- ログイン失敗を正しく診断する
- 不必要な設定変更を避ける
- ユーザーに正確なガイダンスを提供する(「ブラウザが Cookie をブロックした」のではなく、「同意をキャンセル/拒否しました」)
背景
明確にするために、これは関連トピックで議論されている確認済みの iOS アプリ内ブラウザの問題とは別個のものです。そのケースでは、IdP はユーザーの同意の段階に達することさえありませんが、ここでは IdP がユーザーの意図を明示的に報告します。
ログが確認されない限り、どちらも UI レベルでは似たように見えます。
お読みいただきありがとうございます。これは主に、これらのケースが頻繁に発生する学生の多い環境で OIDC を実行している他の人々のためのドキュメントの明確化/データポイントとして投稿しています。
必要であれば、匿名化された例を提供できます。