Ayúdame a solucionar problemas de mi SSO de Discourse

Saludos, espero obtener alguna orientación. Mi SSO dejó de funcionar esta semana y pensé que había solucionado todo ayer (estaba funcionando, lo juro :slight_smile: Nota: Revisé “Nuevos usuarios” de ayer y de hoy, y tenía nuevos usuarios en ambos días (después de solucionarlo), ahora está roto de nuevo…). Lamentablemente, las actualizaciones que realicé no están funcionando hoy.

Problema: Los usuarios no pueden crear nuevas cuentas y los usuarios que cierran sesión no pueden volver a iniciarla.

Noté que mi servidor de Discourse tiene errores 400 en las siguientes rutas:

403: GET: discourse-url/users/by-external/USER-ID.json?
Nota: Recientemente encontré en la documentación de la API que esta ruta no existe (aunque ha funcionado), parece que la ruta es: https://discourse.example.com/u/by-external/{external_id}.json

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

La razón por la que el signo ? está al final es porque tengo un campo de parámetro opcional en una función que genera URLs; para estas dos rutas, todos los datos se envían en el cuerpo del formulario o en los encabezados.

Estoy utilizando la siguiente biblioteca.

Lo que actualicé (y lo que pensé que solucionó el problema):

En todas mis solicitudes, estaba enviando la Api-Key y el Api-Username como parámetros de consulta. Durante los últimos meses, noté en mi panel de administración una advertencia que indicaba que estaba utilizando encabezados obsoletos en mi solicitud. Me vinculó a esta publicación y los detalles clave son los siguientes:

:warning: ¡Advertencia de obsolescencia!
El 6 de abril de 2020 eliminamos el soporte para toda autenticación basada en encabezados no HTTP (excluyendo algunas rutas de RSS, recepción de correo e ICS). Esto significa que las solicitudes de API que tengan un api_key y un api_username en los parámetros de consulta o en el cuerpo HTTP de la solicitud dejarán de funcionar pronto. Consulte el ejemplo de solicitud cURL a continuación para saber cómo actualizar sus solicitudes de API y utilizar los encabezados HTTP para la autenticación.

Actualicé todas mis solicitudes; ahora todas tienen la Api-Key y el Api-Username en el encabezado y el tipo de contenido está configurado como datos de formulario multipart.

Si alguien puede ofrecer orientación sobre qué investigar para depurar este problema, lo agradecería mucho. Estoy casi 100% seguro de que esto funcionaba al final de mi jornada laboral ayer; pude iniciar y cerrar sesión en mi cuenta y pude crear nuevas cuentas.

Por favor, avísenme si necesitan más información. ¡Gracias!

Los campos de la cabecera deben usar guiones (-), no guiones bajos (_). Intenta cambiar los nombres de los campos a Api-Key y Api-Username.

No estoy seguro de si esto solucionará el problema de que los usuarios no puedan iniciar sesión en tu sitio, pero sí corregirá el problema de los errores 400 que estás viendo.

@simon, ¡gracias por la respuesta! Lamentablemente no documenté bien mi publicación, ya estoy usando - y no _ en mis solicitudes.

Para comenzar a depurar esto, ve a la página de configuración de tu sitio Discourse y busca ‘sso’ para obtener todas tus configuraciones de SSO. Asegúrate de que las configuraciones enable sso, sso url y sso secret sean correctas. Luego, habilita la configuración del sitio verbose sso logging. Con esa configuración habilitada, se agregarán algunas entradas de registro adicionales a los registros de errores de tu sitio (que se encuentran en Administración / Registros / Registros de errores).

Intenta iniciar sesión mediante SSO. Luego, revisa tus registros de errores para ver si te brindan detalles sobre el problema. Si no ves nada útil, abre el inspector web de tu navegador en la pestaña Red con la casilla “Preservar registro” marcada. Examina las solicitudes que se están realizando.

Si te bloqueas fuera de tu sitio mientras intentas solucionar el problema, como usuario administrador puedes omitir SSO yendo a /u/admin-login e ingresando tu dirección de correo electrónico en el formulario. Se te enviará un correo electrónico con un enlace de inicio de sesión.

@simon, ¡gracias por el consejo! He estado revisando los registros, pero no tengo mucha experiencia en su lectura. Recibo dos tipos diferentes de advertencias y un error:

Esta es la advertencia que recibo con frecuencia:

Registro detallado de SSO: Proceso de SSO iniciado add_groups: admin: moderator: avatar_force_update: avatar_url: bio: card_background_url: email: external_id: groups: locale: locale_force_update: logo

Este es el error:

Excepción del trabajo: La diferencia entre la hora de la solicitud y la hora actual es demasiado grande.

Cuando intento iniciar sesión con un usuario de prueba en mi sitio, del que ya cerré sesión en Discourse, obtengo lo siguiente en mi panel de red:

503 Servicio no disponible: GET- https://my-site/auth/discourse_sso?sso=XXXX&sig=xxxx

Desafortunadamente, he llegado a un punto muerto y no sé cómo proceder a partir de aquí.

Creo que ese mensaje de error proviene de Amazon S3. Podría haber detalles útiles sobre cómo solucionar el problema en este tema: Backups have started failing due to server time being wrong. Hay más información aquí: https://stackoverflow.com/questions/4770635/s3-error-the-difference-between-the-request-time-and-the-current-time-is-too-la.

@simon ¡gracias por la ayuda! El tiempo de mi servidor estaba desincronizado y lo actualicé; ¡ahora mis copias de seguridad vuelven a funcionar!

Ahora estoy recibiendo esporádicamente un nuevo error:

En la sección de registros, de forma aleatoria obtengo las siguientes advertencias (solo las he recibido 2 veces):

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

y

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

Estoy investigando cómo solucionar este problema. Intenté reconstruir mi aplicación, pero no estoy 100 % seguro de si la reconstrucción fue exitosa. Sigo recibiendo aleatoriamente los errores de “MaxMindDB no se pudo encontrar”, además de los errores 400 y el error 503 que estaba recibiendo anteriormente.

He estado trabajando en esto durante la mayor parte de la madrugada y no he avanzado mucho. Creo que eliminé los errores de MaxMindDB (antes eran esporádicos e inconsistentes; no he podido replicarlos en las últimas 3 horas) y he recompilado mi aplicación varias veces con éxito.

Aquí es donde falla el flujo de SSO:

  • El usuario visita Discourse.
  • Como no hay una sesión activa, el usuario es redirigido a discourse/session/sso_login.
  • El usuario es redirigido a my-site/discourse_sso?sso=XXXX&sig=XXXX.
  • Cuando se accede a la ruta anterior desde mi sitio, hago una solicitud GET a /users/by-external/userId.json.
    • Esto devuelve un 403 Forbidden.
  • Inmediatamente después, se envía una solicitud POST a /admin/users/sync_sso.
    • Esto resulta en un 404: “No route matches [POST] /admin/users/sync_sso.
  • Finalmente, mi sitio devuelve un mensaje de error 503 Forbidden (necesito limpiar algunos de los mensajes de error en mi sitio).

Siento que el error está en el lado de la aplicación Rails (corrígeme si me equivoco). Una razón por la que lo creo es porque, al final del día el viernes, todo funcionaba; hay pruebas de ello, ya que varios usuarios nuevos se registraron entre el viernes por la noche y el sábado (y lo que fallaba era iniciar sesión o crear un nuevo usuario). Como mencioné en publicaciones anteriores, pensé que había solucionado todo entonces; sin embargo, cuando comencé a trabajar el sábado, noté que volvía a estar roto.

No estoy seguro de por qué estás realizando las solicitudes a /users/by-external/<external_id>.json y /admin/users/sync_sso. El flujo normal sería simplemente redirigir al usuario a /session/sso_login con la carga útil de SSO establecida como parámetros de consulta en la URL. Hay detalles sobre para qué se utiliza la ruta sync_sso aquí: Sync DiscourseConnect user data with the sync_sso route.

Realizar una solicitud a /users/by-external/<external_id> con un external_id que aún no está asociado a un usuario de Discourse debería devolver un error 404 (no encontrado). Si el external_id está asociado a un usuario de Discourse, se debe devolver el usuario.

@simon, la solicitud a /users/by-external/USER-ID.json es para verificar si el usuario ya tiene una cuenta en mi Discourse. Si se encuentra un usuario con ese ID, se agrega o elimina de los grupos de Discourse asociados a mi sitio mediante una solicitud PUT a /admin/groups/groupId/members.json y luego se redirige a my-discourse/session/sso_login.

Si el usuario no tiene una cuenta, se crea mediante una solicitud POST a /admin/users/sync_sso. Una vez que el usuario es creado (y agregado a sus grupos de Discourse correspondientes), se redirige a my-discourse/session/sso_login.

Voy a hacer un seguimiento y volver a leer la documentación que mencionaste (¡gracias!). Hemos tenido este flujo funcionando sin problemas desde principios de 2015 (¡y la opción de SSO de Discourse ha sido una herramienta muy valiosa para nosotros!), por lo que es extraño que de repente haya dejado de funcionar la semana pasada.

@simon ¡Realmente agradezco toda tu ayuda! Ya solucioné el problema. El Api-Username que estábamos usando se “desactivó” la semana pasada (debido a la inactividad). Originalmente especulé que eso podría haber sido el problema. Reactivé el usuario el viernes y, muy probablemente, eso fue lo que solucionó todo ese día (originalmente pensé que se debía a mover el Api-Username y la Api-Key al encabezado).

Discourse volvió a desactivar al mismo usuario el sábado por la mañana, lo que explica por qué todo funcionaba y luego de repente dejó de hacerlo. No pensé que el usuario volviera a desactivarse tan pronto por inactividad.

Ahora he cambiado el Api-Username a “system” para evitar que esto vuelva a fallar en el futuro. Gracias de nuevo por tu ayuda; mientras depurábamos esto, mis registros de copia de seguridad volvieron a funcionar y, ¡ciertamente aprendí mucho!