Aidez-moi à résoudre les problèmes de mon SSO Discourse

Bonjour, j’espère obtenir quelques conseils. Mon SSO a cessé de fonctionner cette semaine et je pensais avoir tout réparé hier (cela fonctionnait, je vous le jure :slight_smile: Note : J’ai examiné la section « Nouveaux utilisateurs » d’hier et d’aujourd’hui, et j’avais de nouveaux utilisateurs les deux jours (après ma correction), mais maintenant, c’est à nouveau cassé…). Malheureusement, les mises à jour que j’ai effectuées ne fonctionnent pas aujourd’hui.

Problème : Les utilisateurs ne peuvent pas créer de nouveaux comptes et ceux qui se déconnectent ne peuvent plus se reconnecter.

J’ai remarqué que mon serveur Discourse renvoyait des erreurs 400 sur les routes suivantes :

403 : GET : discourse-url/users/by-external/USER-ID.json?
Note : J’ai récemment découvert dans la documentation de l’API que cette route n’existe pas ? (même si elle a fonctionné auparavant). Il semble que la route soit : https://discourse.example.com/u/by-external/{external_id}.json

404 : POST : discourse-url/admin/users/sync_sso?

La raison pour laquelle le point d’interrogation ? se trouve à la fin est que j’ai un champ de paramètre facultatif dans une fonction qui génère des URL. Pour ces deux routes, toutes les données sont envoyées dans le corps du formulaire ou dans les en-têtes.

J’utilise la bibliothèque suivante.

Ce que j’ai mis à jour (et ce que je pensais avoir résolu le problème) :

Dans toutes mes requêtes, j’envoyais l’Api-Key et l’Api-Username via un paramètre de requête. Au cours des derniers mois, j’ai remarqué dans mon panneau d’administration un avertissement indiquant que j’utilisais des en-têtes obsolètes dans ma requête. Cela m’a renvoyé vers ce post, et les points clés sont les suivants :

:warning: Avertissement de dépréciation !
Le 6 avril 2020, nous avons supprimé le support de toutes les authentifications basées sur des éléments autres que les en-têtes HTTP (à l’exception de certains itinéraires RSS, de réception de courriels et de ICS). Cela signifie que les requêtes API contenant un api_key et un api_username dans les paramètres de requête ou dans le corps HTTP de la requête cesseront bientôt de fonctionner. Veuillez consulter l’exemple de requête cURL ci-dessous pour savoir comment mettre à jour vos requêtes API afin d’utiliser les en-têtes HTTP pour l’authentification.

J’ai mis à jour toutes mes requêtes ; désormais, toutes mes requêtes contiennent l’Api-Key et l’Api-Username dans l’en-tête, et le type de contenu est défini sur multipart/form-data.

Si quelqu’un peut me donner des conseils sur les pistes à explorer pour déboguer ce problème, je le remercie vivement. Je suis presque certain à 100 % que cela fonctionnait à la fin de ma journée de travail hier : j’ai pu me connecter et me déconnecter de mon compte, et j’ai pu créer de nouveaux comptes.

N’hésitez pas à me dire si vous avez besoin de plus d’informations. Merci !

Les champs d’en-tête doivent utiliser des tirets (-) et non des tirets bas (_). Essayez de modifier les noms des champs en Api-Key et Api-Username.

Je ne sais pas si cela résoudra le problème empêchant les utilisateurs de se connecter à votre site, mais cela corrigera le problème des erreurs 400 que vous rencontrez.

@simon, merci pour ta réponse ! Malheureusement, je n’ai pas bien documenté mon message : j’utilise déjà - et non _ dans mes requêtes.

Pour commencer le débogage, accédez à la page des paramètres de votre site Discourse et recherchez « sso » pour obtenir tous vos paramètres SSO. Assurez-vous que les paramètres enable sso, sso url et sso secret sont corrects. Ensuite, activez le paramètre de site verbose sso logging. Une fois ce paramètre activé, des entrées de journal supplémentaires seront ajoutées aux journaux d’erreurs de votre site (trouvés dans Admin / Journaux / Journaux d’erreurs).

Essayez de vous connecter via SSO. Ensuite, consultez vos journaux d’erreurs pour voir s’ils vous donnent des détails sur le problème. Si vous ne voyez rien d’utile, ouvrez l’inspecteur web de votre navigateur sur l’onglet Réseau avec la case à cocher « Conserver le journal » activée. Examinez les requêtes qui sont effectuées.

Si vous vous verrouillez hors de votre site tout en essayant de résoudre le problème, en tant qu’utilisateur administrateur, vous pouvez contourner le SSO en allant sur /u/admin-login et en saisissant votre adresse e-mail dans le formulaire. Un e-mail vous sera envoyé avec un lien de connexion.

@simon, merci pour l’astuce ! J’ai examiné les journaux, mais je ne suis pas très expérimenté dans leur lecture. Je rencontre deux types d’avertissements différents et une erreur :

Voici l’avertissement que je reçois fréquemment :

Journal SSO verbeux : Démarrage du processus SSO add_groups : admin : modérateur : avatar_force_update : avatar_url : bio : card_background_url : email : external_id : groups : locale : locale_force_update : logo

Voici l’erreur :

Exception de tâche : La différence entre l'heure de la requête et l'heure actuelle est trop importante.

Lorsque j’essaie de me connecter avec un utilisateur de test sur mon site, que j’ai déconnecté sur Discourse, j’obtiens le suivant dans mon panneau réseau :

503 Service indisponible : GET- https://my-site/auth/discourse_sso?sso=XXXX&sig=xxxx

Malheureusement, je suis bloqué et ne sais pas comment avancer à partir d’ici.

Je pense que ce message d’erreur provient d’Amazon S3. Vous trouverez peut-être des détails utiles sur la façon de résoudre le problème dans ce sujet : Backups have started failing due to server time being wrong. Il y a également plus d’informations ici : https://stackoverflow.com/questions/4770635/s3-error-the-difference-between-the-request-time-and-the-current-time-is-too-la.

@simon merci pour ton aide ! L’heure de mon serveur n’était pas synchronisée, je l’ai corrigée et mes sauvegardes fonctionnent à nouveau !

Maintenant, je rencontre sporadiquement une nouvelle erreur :

Dans la section des journaux, j’obtiens aléatoirement les avertissements suivants (je ne les ai reçus que deux fois) :

MaxMindDB (/var/www/discourse/vendor/data/GeoLite2-City.mmdb) introuvable : No such file or directory @ rb_sysopen - /var/www/discourse/vendor/data/GeoLite2-City.mmdb

et

MaxMindDB (/var/www/discourse/vendor/data/GeoLite2-ASN.mmdb) introuvable : No such file or directory @ rb_sysopen - /var/www/discourse/vendor/data/GeoLite2-ASN.mmdb

Je suis en train de chercher comment résoudre ce problème. J’ai essayé de reconstruire mon application, mais je ne suis pas sûr à 100 % que la reconstruction ait réussi. Je continue de recevoir aléatoirement les erreurs MaxMindDB introuvable, en plus des erreurs 400 et de l’erreur 503 que je rencontrais précédemment.

Je travaille sur ce problème depuis la plupart de la matinée et n’ai pas beaucoup avancé. Je pense avoir éliminé les erreurs MaxMindDB (elles étaient sporadiques et incohérentes plus tôt ; je n’ai pas réussi à les reproduire depuis 3 heures) et j’ai reconstruit mon application plusieurs fois avec succès.

Voici où le pipeline SSO échoue :

  • Un utilisateur visite Discourse
  • Comme il n’y a pas de session active, l’utilisateur est redirigé vers discourse/session/sso_login
  • L’utilisateur est redirigé vers my-site/discourse_sso?sso=XXXX&sig=XXXX
  • Lorsque la route précédente de mon site est atteinte, j’envoie une requête GET vers /users/by-external/userId.json
    • cela renvoie une erreur 403 Forbidden
  • Immédiatement après, une requête POST est envoyée vers /admin/users/sync_sso
    • cela entraîne une erreur 404 "No route matches [POST] /admin/users/sync_sso
  • Finalement, mon site renvoie un message d’erreur 503 Forbidden (je dois nettoyer certains messages d’erreur de mon côté)

J’ai l’impression que l’erreur se trouve du côté de l’application Rails (corrigez-moi si je me trompe). Une raison pour laquelle je pense cela est que, à la fin de la journée vendredi, tout fonctionnait. Il y a une preuve puisque quelques nouveaux utilisateurs se sont inscrits entre vendredi soir et samedi (et se connecter ou créer un nouvel utilisateur était ce qui était cassé). Comme je l’ai mentionné dans des messages précédents, je pensais avoir tout réparé à ce moment-là, mais lorsque j’ai commencé à travailler samedi, j’ai remarqué que c’était à nouveau cassé.

Je ne suis pas sûr de la raison pour laquelle vous effectuez des requêtes vers /users/by-external/<external_id>.json et /admin/users/sync_sso. Le flux normal consisterait simplement à rediriger l’utilisateur vers /session/sso_login, en définissant la charge utile SSO comme paramètres de requête dans l’URL. Vous trouverez des détails sur l’utilisation de l’itinéraire sync_sso ici : Sync DiscourseConnect user data with the sync_sso route.

Une requête vers /users/by-external/<external_id> avec un external_id qui n’est pas encore associé à un utilisateur Discourse doit renvoyer une erreur 404 (non trouvé). Si l’external_id est déjà associé à un utilisateur Discourse, cet utilisateur doit être renvoyé.

@simon, La requête vers /users/by-external/USER-ID.json sert à vérifier si l’utilisateur possède déjà un compte sur mon Discourse. Si un utilisateur est trouvé avec cet identifiant, il est ajouté ou retiré des groupes Discourse associés à mon site via une requête PUT vers /admin/groups/groupId/members.json, puis il est redirigé vers my-discourse/session/sso_login.

Si l’utilisateur ne possède pas de compte, celui-ci est créé via une requête POST vers /admin/users/sync_sso. Une fois le compte créé (et l’utilisateur ajouté aux groupes Discourse appropriés), il est redirigé vers my-discourse/session/sso_login.

Je vais faire un suivi et relire la documentation que vous avez mentionnée (merci !). Nous utilisons ce flux sans aucun problème depuis début 2015 (et l’option SSO de Discourse a été un outil extrêmement précieux pour nous !), il est donc étrange qu’il ait soudainement cessé de fonctionner la semaine dernière.

@simon Je vous remercie vraiment pour toute votre aide ! J’ai résolu le problème. Le Api-Username que nous utilisions a été « désactivé » la semaine dernière (en raison d’inactivité). J’avais initialement émis l’hypothèse que cela pouvait être la cause du problème. J’ai réactivé l’utilisateur vendredi, et il est fort probable que cela ait tout résolu ce jour-là (j’avais initialement pensé que c’était le déplacement du Api-Username et de la Api-Key dans l’en-tête).

Discourse a à nouveau désactivé le même utilisateur samedi matin, ce qui explique pourquoi tout fonctionnait avant de s’arrêter soudainement. Je ne pensais pas que l’utilisateur serait à nouveau désactivé si rapidement en raison d’inactivité.

J’ai maintenant modifié le Api-Username en « system » pour éviter que cela ne se reproduise à l’avenir. Encore merci pour votre aide ; en déboguant ce problème, mes journaux de sauvegarde fonctionnent à nouveau et j’ai certainement beaucoup appris !