Poursuite de la discussion sur La connexion OIDC via l’application iOS Discourse échoue occasionnellement avec csrf_detected lors du rappel :
Bonjour à tous,
Ceci est une observation de suivi liée à mon fil de discussion précédent sur les échecs de connexion OIDC initiés depuis les navigateurs intégrés d’iOS. Cette discussion s’est concentrée sur les échecs déterministes de csrf_detected causés par l’isolement des cookies de WKWebView, qui sont maintenant bien compris et attendus.
Ce sujet lié concerne la clarté pour les opérateurs, pas un bogue.
Observation
En enquêtant sur une série d’échecs de connexion OIDC, j’ai remarqué que la même erreur de surface dans Discourse :
/auth/oidc/callback → /auth/failure?message=csrf_detected
peut correspondre à plusieurs causes profondes fondamentalement différentes, selon ce que l’IdP (Identity Provider) a renvoyé.
À partir de l’interface utilisateur de l’application seule, ces cas sont indiscernables. La différence n’est visible qu’en inspectant Admin → Logs → env / params.
Exemples observés en pratique (Azure / Entra ID)
En plus de la perte de cookies du navigateur intégré, j’ai observé des rappels où Entra ID renvoie explicitement des erreurs structurées telles que :
L’utilisateur a refusé le consentement
error=consent_required
error_description=AADSTS65004: User declined to consent to access the app
L’utilisateur a annulé la connexion
error=access_denied
error_subcode=cancel
Dans les deux cas :
- Azure a identifié l’utilisateur avec succès
- L’utilisateur a explicitement choisi de ne pas continuer (refuser / annuler)
- Discourse reçoit le rappel
- Le flux se résout finalement à
/auth/failure?message=csrf_detected
Du point de vue de Discourse, il s’agit d’un comportement correct et sécurisé - l’état ne peut pas être validé ou complété - mais la raison sous-jacente est très différente de celle d’un cookie de session manquant.
Pourquoi c’est important pour les opérateurs
Sans vérifier l’environnement/les paramètres des journaux, un administrateur voyant des échecs répétés de csrf_detected peut raisonnablement supposer :
- des cookies cassés
- une mauvaise configuration de SameSite
- des problèmes de navigateur mobile
- une instabilité de l’IdP
… alors qu’en réalité, certains de ces échecs sont simplement dus au fait que les utilisateurs choisissent de ne pas donner leur consentement ou d’annuler l’invite Microsoft.
Cette distinction ne devient claire que si vous savez déjà qu’il faut inspecter la charge utile brute du journal.
Suggestion (documentation / UX uniquement)
Je ne suggère aucun changement de comportement pour OmniAuth ou la gestion de CSRF.
Il pourrait être utile que la documentation ou les conseils de dépannage notent explicitement que :
csrf_detectedpeut être l’erreur finale pour de multiples résultats d’IdP en amont- y compris des actions explicites de l’utilisateur comme annuler ou refuser le consentement
- et que les administrateurs doivent inspecter Admin → Logs → env / params pour distinguer ces cas
Cela faciliterait pour les opérateurs :
- le diagnostic correct des échecs de connexion
- l’évitement de changements de configuration inutiles
- et la fourniture de conseils précis aux utilisateurs (« vous avez annulé / refusé le consentement » contre « votre navigateur a bloqué les cookies »).
Contexte
Pour être clair : ceci est distinct du problème confirmé du navigateur intégré iOS discuté dans le sujet lié. Dans ce cas, l’IdP n’atteint jamais le stade du consentement de l’utilisateur, alors qu’ici l’IdP signale explicitement l’intention de l’utilisateur.
Les deux apparaissent de manière similaire au niveau de l’interface utilisateur à moins que les journaux ne soient examinés.
Merci d’avoir lu - je publie ceci principalement comme un point de clarté documentaire/un point de données pour les autres qui gèrent OIDC dans des environnements à forte population étudiante où ces cas surviennent fréquemment.
Je suis disponible pour fournir des exemples anonymisés si cela est utile.