Verwenden Sie Discourse als Identitätsanbieter (SSO, DiscourseConnect)

Ich konnte damit ein Account-Verknüpfungssystem für meinen Minecraft-Server erstellen! Ich dachte, ich teile, wie es aussieht! Es war das erste Mal, dass ich mit Discourse SSO gearbeitet habe, also habe ich vielleicht alles überkompliziert. Aber es funktioniert, und das ist die Hauptsache.

4 „Gefällt mir“

Hallo, ich habe all das richtig gemacht. Aber wenn der Benutzer nicht bei Discourse angemeldet ist, wird das Anmelde-Popup für Benutzer angezeigt. Wenn ich Benutzername und Passwort eingebe, werde ich nicht zur Rückkehr-URL zurückgeleitet. Können Sie mir bitte helfen?

Ich gehe davon aus, dass die nonce dazu dient, Wiederholungsangriffe zu verhindern. Ich habe online gelesen, dass Wiederholungsangriffe mit HTTPS, das ich verwende, nicht möglich sind. Muss ich die nonce also trotzdem verwenden? Ich frage, weil ich nicht sicher bin, wo ich sie speichern soll. Macht es Sinn, sie als sicheres, unverschlüsseltes Cookie im Browser des Benutzers zu speichern? und sie dann zusammen mit der Rückgabennutzlast aus dem Browser zu lesen?

Diese Bibliothek, die aus dem ursprünglichen Beitrag verlinkt ist GitHub - ArmedGuy/discourse_sso_node: npm package for Discourse SSO login features., verwendet die nonce nicht bei der Validierung des Benutzers.

Ja, Sie müssen die Nonce trotzdem validieren, da sie die Wiederverwendung von Payloads verhindert, die Discourse sendet, wenn es Benutzer auf Ihre Website zurückleitet.

Angenommen, Ihre Website hat Inhalte hinter einer Paywall, auf die nur Mitglieder der Gruppe subscribers in Discourse zugreifen können, und Sie verwenden das Feld groups in der Payload, die Discourse an Ihre Website sendet, um die bezahlten Inhalte nur für Mitglieder der Gruppe subscribers anzuzeigen. Wenn Sie die Nonce nicht validieren, könnte ein Benutzer, der nicht mehr in der Gruppe subscribers ist, eine alte Payload aus der Zeit verwenden, als er Mitglied war, um sich auf Ihrer Website anzumelden und die bezahlten Inhalte anzuzeigen.

Es ist am besten, die Nonce in einer Datenbank mit einem kurzen Ablaufdatum zu speichern und die Nonce aus der Datenbank zu löschen, sobald sie verwendet wurde. Wenn Sie jedoch keine Datenbank verwenden können, können Sie einen Cookie verwenden, um die Nonce zu speichern. Sie müssen jedoch einige zusätzliche Schritte unternehmen, um die Wiederverwendung von Payloads zu verhindern:

  1. Hängen Sie ein Ablaufdatum an die Nonce an, wenn Sie sie generieren, z. B. 10 Minuten ab der aktuellen Zeit.
  2. Signieren Sie den gesamten Cookie (Nonce + Ablaufdatum), um zu verhindern, dass Benutzer die Nonce und/oder das Ablaufdatum ändern.
  3. Überprüfen Sie die Signatur des Cookies und stellen Sie sicher, dass die Nonce nicht abgelaufen ist.

Dies sollte Ihnen einen ausreichenden Schutz gegen die Wiederverwendung von Payloads bieten. Beachten Sie, dass es technisch gesehen immer noch möglich ist, eine Payload wiederzuverwenden, aber dies ist auf ein Zeitfenster von 10 Minuten beschränkt und nicht für immer.

Eine einfachere Lösung, die keinen Cookie benötigt, besteht darin, das Ablaufdatum in einem benutzerdefinierten Feld in der von Ihnen generierten Payload einzuschließen. Wenn Discourse Benutzer dann mit einer Payload auf Ihre Website zurückleitet, werden Ihre benutzerdefinierten Felder einbezogen und Sie können das Ablaufdatum abrufen und überprüfen, ob es nicht abgelaufen ist. Um ein benutzerdefiniertes Feld in die Payload aufzunehmen, müssen Sie ein Feld mit dem Präfix custom. einfügen. Ihre Payload würde dann wie folgt aussehen:

nonce=NONCE&return_sso_url=RETURN_URL&custom.expiration_date=TIMESTAMP
4 „Gefällt mir“

Sie könnten den Nonce auch in der Sitzung speichern, das hindert den Benutzer ebenfalls daran, ihn zu manipulieren.

3 „Gefällt mir“

Ich komme Jahre später auf diesen Thread zurück

Kann mir jemand (@pfaffman oder @tobiaseigen oder @iamntz) sagen, was der Discourse SSO-Anbieter zurückgibt? Ich weiß, dass ich es „versuchen und sehen“ kann, aber es wäre schön, wenn es dokumentiert wäre. Der PHP-Beispielcode auf GitHub erwähnt kaum andere Felder.

Idealerweise würde er dieselben Felder senden, wie wenn Discourse das externe Skript für SSO verwendet, wie externe ID, E-Mail, Benutzername, Name, Avatarfoto usw. So können wir dies importieren und einen Benutzer auf unserer Seite erstellen!

Teilt es WordPress auch die E-Mail-Adresse mit?

Wie sieht es mit Gruppen, Abzeichen usw. aus? Können wir diese Informationen durch REST-Aufrufe finden?

Schließlich, was ist mit den privaten Nachrichten und anderen Dingen des Benutzers? Ich schätze, wenn Discord ein OAuth-Anbieter wäre und es unseren Apps erlauben würde, diese Dinge zu konsumieren, wäre das großartig.

Wenn ich versuche, Discourse Connect zu aktivieren, erhalte ich diese Fehlermeldung:
enable_discourse_connect: Sie können DiscourseConnect und nur Einladungen nicht gleichzeitig aktivieren.

Irgendwelche Ideen?

Ich sehe, dass Sie hier dieselbe Frage gestellt haben: Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) - #537. Wenn Sie versuchen, die Einstellung enable discourse connect zu konfigurieren und nicht die Einstellung enable discourse connect provider, ist das andere Thema der richtige Ort, um Ihre Frage zu stellen.

Die Einstellung enable discourse connect provider ist für den Fall gedacht, dass Sie Ihre Discourse-Site als Identitätsanbieter für eine andere Site verwenden möchten. Die Einstellung enable discourse connect ist für den Fall gedacht, dass Sie Benutzer über eine externe Site bei Discourse anmelden möchten.

1 „Gefällt mir“

Ich habe das Verfahren in Python für eine Flask-Anwendung implementiert, die ich gerade erstelle. Hier ist etwas Boilerplate-Code für alle, die ihn benötigen. Die in diesem Thema dargelegten Schritte waren ziemlich einfach zu befolgen, aber ich bin kein Sicherheitsspezialist. Wenn ich also etwas übersehen habe, lassen Sie es mich bitte wissen!

https://gist.github.com/ScottMastro/011b7a823177ae9022aac35cee

2 „Gefällt mir“

Wir versuchen, Discourse als SSO-Anbieter zu implementieren, und wir verstehen nicht, wie Discourse weiß, welcher Benutzer verifiziert werden muss. Die Anweisungen lauten: „Erstellen Sie eine neue Nutzlast mit Nonce und Rückruf-URL“. Aber wenn Sie dies über einen Fetch an Discourse senden, woher weiß Discourse, welchen Benutzer es überprüfen soll, um festzustellen, ob er angemeldet ist? Entschuldigen Sie, wenn dies wie eine dumme Frage klingt, aber ich verstehe einfach nicht, wie das funktioniert, und ich habe im Laufe der Jahre mit vielen Authentifizierungssystemen gearbeitet, bin also einigermaßen vertraut. Muss die E-Mail-Adresse des Benutzers, für den wir den Anmeldestatus überprüfen möchten, in die an Discourse gesendete Nutzlast aufgenommen werden? Wenn ja, wie genau ist die Struktur der Nutzlast, die an Discourse gesendet werden muss? Wenn nicht, was genau überprüft Discourse dann? Meine Annahme ist, dass wir den Benutzer auf unserer Seite nach seiner E-Mail-Adresse fragen und dann die Nutzlast mit der E-Mail an Discourse senden, um zu sehen, ob dieser bestimmte Benutzer angemeldet ist, aber das ist nicht das, was die Anweisungen sagen, daher bin ich völlig verwirrt. Danke für jede Hilfe.

Schon gut. Wir haben das herausgefunden. Wir dachten, die SSO-URL müsste als POST-Anfrage an die Discourse-Instanz gesendet und dann eine Antwort empfangen werden. Jetzt sehen wir, dass dies eine Weiterleitung zu Discourse ist und Discourse dann zurück zu unserer Website weiterleitet. Es ist also jetzt klar, was zu tun ist. Entschuldigung für den vorherigen Beitrag.

3 „Gefällt mir“

FYI/FWIW: Ich habe einen PR eingereicht, um einen prompt=none-Parameter in der Auth-Anfrage zu ermöglichen. Ähnlich wie eine Funktion im OpenID Connect-Protokoll ermöglicht dies einem SSO-Konsumenten zu prüfen, ob ein Benutzer/Client bereits angemeldet ist, ohne ihn zu einem Anmeldedialog zu senden, falls er nicht angemeldet ist.

Der PR wartet nun seit etwa 8 Wochen auf eine endgültige Überprüfung durch jemanden aus dem Discourse-Team; das scheint mir ziemlich viel länger als erwartet. :crying_cat_face:

7 „Gefällt mir“

Hallo @mdoggydog – Entschuldigung für die sehr lange Verzögerung hier!

Ich habe den PR gerade überprüft und zusammengeführt – danke für deinen Beitrag! :raised_hands:

3 „Gefällt mir“

Prima! Danke, @david.

Wie versprochen habe ich gerade den Wiki-Artikel hier aktualisiert, um eine Beschreibung des neuen Parameters (und des früheren neuen logout-Parameters aufzunehmen, einige kleinere Tippfehler/Grammatikfehler zu beheben und einen Referenzabschnitt hinzuzufügen, der die sso=-Nutzlast dokumentiert, wie ich sie aus dem Quellcode verstehe).

2 „Gefällt mir“

Ich möchte unsere Website nicht mehr als SSO für Discourse verwenden und stattdessen die integrierten Anmeldetools von Discourse nutzen, um den Zugriff auf bestimmte Materialien auf unserer Website zu beschränken.

Ich glaube, das richtige Werkzeug dafür ist: GitHub - discourse/discourse-auth-proxy: An http proxy that uses the DiscourseConnect protocol to authenticate users

Ich habe keine ausführlichen Anleitungen zur Verwendung gefunden.

Kann ich das auf demselben DigitalOcean-Droplet wie unsere Discourse-Site installieren oder muss ich es woanders hosten?

Bearbeiten: Habe meine Frage fett hervorgehoben :slight_smile:

1 „Gefällt mir“

Kann jemand bei der obigen Frage helfen? Use Discourse as an identity provider (SSO, DiscourseConnect) - #148 by alehandrof

Ich setze als return_sso_url eine URL, die selbst einen Query-Parameter hat:

http://localhost:7000/completeLogin?returnto=%2F

Die Payload, die ich an /session/sso_provider als sso-Parameter sende, sieht vor der Base64-Kodierung so aus:

nonce=ENIwf0bElViDu325dTd6&return_sso_url=http://localhost:7000/completeLogin?returnto=%2F

Die URL, zu der Discourse nach der Authentifizierung tatsächlich weiterleitet, ist diese (mit den sso- und sig-Parametern abgekürzt):

http://localhost:7000/completeLogin?returnto=/\u0026sso=...\u0026sig=...

Was mich hier überrascht, ist, dass die Query-String, die ich für return_sso_url gesetzt habe, von etwas urldecodiert zu sein scheint, denn sie hat returnto=/ anstelle von returnto=%2F. Der Wert von return_sso_url, den ich innerhalb von sso nach der Base64-Dekodierung finde, hat ebenfalls einen Schrägstrich anstelle von %2F.

Ist das so zu erwarten? (Wenn ja, warum?) Ist das ein Bug in Discourse?

Was ist der Grund dafür, dass die sso-Nutzlast avatar_url anstelle von avatar_template enthält, wie es in /u/{username}.json und /session/current.json zurückgegeben wird?

avatar_url ist für Benutzer, die keinen Avatar festgelegt haben, nicht vorhanden, während avatar_template den leter_avatar_proxy-Pfad enthält, der tatsächlich in Discourse verwendet wird, um Avatare für diese Benutzer anzuzeigen, und avatar_url auf das Rohbild des Avatars verweist, anstatt auf eines, das für Benutzer, die einen Avatar festgelegt haben, auf die gewünschte Größe skaliert ist.

Mir scheint, dass avatar_template das ist, was jeder, der die im sso enthaltenen Avatarinformationen verwenden möchte, wünschen wird – aber dann eine zusätzliche API-Anfrage stellen muss, um sie zu erhalten.

2 „Gefällt mir“

Ich implementiere gerade SSO in meiner App, das Login funktioniert bisher sehr gut, das Logout nicht.

Meine Discourse-Instanz leitet korrekt zur Rückgabe-URL zurück, ohne sso- oder sig-Parameter, aber wenn ich Discourse öffne, ist mein Konto immer noch angemeldet.

Irgendwelche Ideen?

Ich gehe davon aus, dass Sie die Discourse-Einstellung logout redirect verwenden, um Benutzer nach dem Abmelden von Discourse zu Ihrer App zurückzuleiten.
Eine mögliche Ursache für das Problem wäre, wenn die Einstellung login required auf Ihrer Discourse-Site aktiviert ist. Wenn diese Einstellung aktiviert ist, leitet Discourse nicht authentifizierte Benutzer automatisch zur SSO-Anbieter-Site weiter, wenn sie direkt auf die Discourse-Site zugegriffen haben. Das bedeutet, dass Benutzer automatisch bei Discourse angemeldet werden, wenn sie das nächste Mal die Website besuchen, es sei denn, Sie melden die Benutzer in Ihrer App ab, wenn sie zuerst zur logout redirect-URL weitergeleitet werden. Sie können dieses Verhalten bestätigen, indem Sie den Vorgang mit dem geöffneten Netzwerk-Tab des Inspektors Ihres Browsers durchlaufen.
Falls es nützlich ist, hier ist, wie das WP Discourse-Plugin den Discourse-Logout-Redirect handhabt: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

2 „Gefällt mir“