¡Hola! Hemos creado un plugin SSO personalizado para agrupar los detalles de inicio de sesión de nuestra empresa en un paquete que Discourse pueda utilizar para gestionar los inicios de sesión y la creación de cuentas. Con la versión v2.7.0beta4, empezamos a recibir errores indicando que no estábamos proporcionando un nuevo parámetro: secure_session. No he encontrado ninguna información sobre el formato que debe tener este parámetro ni sobre su contenido. ¿Existe alguna documentación adicional sobre esta actualización?
¿Sabes cuál es el mensaje de error exacto que estás viendo? Mi entendimiento es que Discourse ahora vincula el parámetro nonce del SSO con la sesión del usuario. Esto significa que si una aplicación ha estado generando el nonce mediante una solicitud en segundo plano a /session/sso, el nonce no será válido. Posiblemente este sea el problema que estás encontrando.
El archivo service_gateway_current_user.rb forma parte de nuestro plugin para construir la carga útil que se enviará a DiscourseSingleSignOn basándose en los encabezados “Service Gateway” (“Service Gateway” es nuestra estructura interna de la empresa para determinar si has iniciado sesión en nuestro sistema).
Para explicar esa parte de la pila:
Nuestra función current_user utiliza nuestros encabezados para buscar un SingleSignOnRecord donde el external_id coincida con el ID de usuario en los encabezados. Si no es así, entramos en la sección create_sso_record.
create_sso_record crea un hash – { external_id: sg_headers[:user_id], email: sg_headers[:email] } – y lo envía a nuestra función upsert_sso_record.
upsert_sso_record toma ese hash (payload en el contexto a continuación) e intenta crear un objeto DiscourseSingleSignOn:
def upsert_sso_record(payload)
encoded_query = Base64.encode64(payload.to_query)
sig = OpenSSL::HMAC.hexdigest('sha256', ENV['SSO_SECRET'], encoded_query)
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query)
if SiteSetting.verbose_sso_logging
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
Rails.logger.warn("SSO Payload:\n\n#{payload}")
end
begin
user = sso.lookup_or_create_user(@request.ip)
rescue ActiveRecord::RecordInvalid => ex
Rails.logger.error "Unable to find/create sso user #{ex}"
end
user
end
La llamada a parse en la tercera línea de esa función es donde parece estar surgiendo el problema. Una vez que intenta initialize el objeto, el valor secure_session que espera no está presente.
Me pregunto si establecer la nueva configuración del sitio discourse_connect_csrf_protection en false solucionará el problema para ti. Esa configuración del sitio está oculta, por lo que debe establecerse desde la consola de Rails. Puedes encontrar detalles al respecto en las respuestas a este tema: DiscourseConnect flow no longer functions.
Lamentablemente, creo que esa nueva configuración no ayudará por sí sola: los detalles internos del código seguirán requiriendo pasar un objeto secure_session, aunque no se utilice.
En general, recomendamos usar los hooks oficiales para los plugins de autenticación, en lugar de sobrescribir la implementación de DiscourseConnect del núcleo.
Es difícil saber con certeza sin ver todo el plugin, pero podrías intentar pasar un valor nil para secure_session. Hacer eso, junto con activar la nueva configuración del sitio, podría ayudar a acercarse un poco más al funcionamiento correcto.
Después de investigar un poco más el código de v2.7.0.beta4, veo que ApplicationController tiene una definición de secure_session. Modificar nuestro código del plugin de la siguiente manera parece funcionar en nuestro entorno de Staging:
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query, secure_session: secure_session)