Hallo! Wir haben ein benutzerdefiniertes SSO-Plugin entwickelt, um die Anmeldedaten unseres Unternehmens in ein Paket zu bündeln, das Discourse zur Verarbeitung von Anmeldungen und zur Erstellung von Konten nutzen kann. Seit der Version v2.7.0beta4 erhalten wir Fehlermeldungen, dass wir einen neuen Parameter, secure_session, nicht bereitstellen. Ich kann nirgendwo Details darüber finden, welches Format dieser Parameter haben soll und was er enthalten muss. Gibt es zusätzliche Dokumentation zu diesem Update?
Weißt du, welche genaue Fehlermeldung angezeigt wird? Mein Verständnis ist, dass Discourse den SSO-Parameter nonce nun an die Sitzung des Benutzers bindet. Das bedeutet, dass der nonce ungültig ist, wenn eine App diesen durch einen Hintergrundantrag an /session/sso generiert. Möglicherweise ist dies das Problem, auf das du stößt.
Die Datei service_gateway_current_user.rb ist Teil unseres Plugins, das den Payload für die Übertragung an DiscourseSingleSignOn erstellt, basierend auf den „Service Gateway“-Headern („Service Gateway“ ist unsere firmeninterne Struktur zur Feststellung, ob Sie in unserem System eingeloggt sind).
Zur Erklärung dieses Teils des Stack-Traces:
Unsere Funktion current_user nutzt unsere Header, um einen SingleSignOnRecord zu suchen, bei dem die external_id mit der Benutzer-ID in den Headern übereinstimmt. Ist dies nicht der Fall, wechseln wir in den Abschnitt create_sso_record.
create_sso_record erstellt einen Hash – { external_id: sg_headers[:user_id], email: sg_headers[:email] } – und sendet diesen an unsere Funktion upsert_sso_record.
upsert_sso_record nimmt diesen Hash (payload im folgenden Kontext) und versucht, ein DiscourseSingleSignOn-Objekt zu erstellen:
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
Der Aufruf von parse in der dritten Zeile dieser Funktion scheint das Problem zu verursachen. Sobald versucht wird, das Objekt zu initialisieren, fehlt der erwartete Wert secure_session.}
Ich frage mich, ob das Setzen der neuen Site-Einstellung discourse_connect_csrf_protection auf false das Problem für dich lösen wird. Diese Site-Einstellung ist versteckt und muss daher über die Rails-Konsole gesetzt werden. Details dazu findest du in den Antworten auf dieses Thema: DiscourseConnect flow no longer functions.
Leider glaube ich nicht, dass diese neue Einstellung allein helfen wird – die Code-Interna erfordern weiterhin das Übergeben eines secure_session-Objekts, auch wenn es nicht verwendet wird.
Im Allgemeinen empfehlen wir, für Authentifizierungs-Plugins die offiziellen Hooks zu verwenden, anstatt die DiscourseConnect-Implementierung des Kerns zu überschreiben.
Es ist schwierig, dies ohne den gesamten Plugin-Code sicher zu sagen, aber Sie könnten versuchen, einen nil-Wert für secure_session zu übergeben. Das könnte, zusammen mit dem Aktivieren der neuen Site-Einstellung, vielleicht helfen, die Dinge ein Stück weit funktionsfähig zu machen.
Nach weiterer Analyse des v2.7.0.beta4-Code sehe ich, dass ApplicationController eine secure_session-Definition enthält. Das Ändern unseres Plugin-Codes auf Folgendes scheint in unserer Staging-Umgebung zu funktionieren:
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query, secure_session: secure_session)