Discourse OAuth2 Basic

:discourse2: Zusammenfassung Discourse OAuth2 Basic unterstützt grundlegende OAuth2-Anbieter, sofern diese einen JSON-API-Endpunkt bereitstellen, über den Benutzerdaten per Token abgerufen werden können.
:open_book: Installationsanleitung Dieses Plugin ist im Discourse-Kern enthalten. Eine separate Installation ist nicht erforderlich.

Funktionen

Dieses Plugin ermöglicht die Nutzung eines grundlegenden OAuth2-Anbieters als Authentifizierungsmethode für Discourse. Es sollte mit vielen Anbietern funktionieren, wobei zu beachten ist, dass diese einen JSON-Endpunkt zur Abfrage von Informationen über den sich anmeldenden Benutzer bereitstellen müssen.

Dies ist vor allem für Personen nützlich, die Login-Anbieter verwenden, die nicht sehr verbreitet sind. Wenn Sie Google, Facebook oder Twitter nutzen möchten, sind diese bereits integriert, und Sie benötigen dieses Plugin nicht. Weitere Login-Anbieter finden Sie auch in unserem Github-Repo.

Konfiguration

Grundkonfiguration

  1. Registrieren Sie zunächst Ihre Discourse-Anwendung bei Ihrem OAuth2-Anbieter. Dazu wird eine Redirect-URI benötigt, die wie folgt lautet:

    http://DISCOURSE_HOST/auth/oauth2_basic/callback

:information_source: Ersetzen Sie DISCOURSE_HOST durch den entsprechenden Wert und stellen Sie sicher, dass Sie https verwenden, falls aktiviert. Der OAuth2-Anbieter sollte Ihnen eine client ID und ein secret sowie einige URLs bereitstellen.

  1. Besuchen Sie Ihren Admin-Bereich → EinstellungenOAuth2-Login und füllen Sie die Grundkonfiguration für den OAuth2-Anbieter aus:
  • oauth2_enabled - aktivieren Sie diese Option, um die Funktion zu ermöglichen
  • oauth2_client_id - die Client-ID Ihres Anbieters
  • oauth2_client_secret - das Client-Secret Ihres Anbieters
  • oauth2_authorize_url - die Autorisierungs-URL Ihres Anbieters
  • oauth2_token_url - die Token-URL Ihres Anbieters.

:information_source: Wenn Sie die Werte für die oben genannten Einstellungen nicht herausfinden können, konsultieren Sie die Entwicklerdokumentation Ihres Anbieters oder wenden Sie sich an deren Kundensupport.

Konfiguration des JSON-Benutzerendpunkts

Discourse kann nun einen Autorisierungstoken von Ihrem OAuth2-Anbieter empfangen. Leider benötigt Discourse weitere Informationen, um die Authentifizierung abschließen zu können.

Wir benötigen einen API-Endpunkt, der kontaktiert werden kann, um Benutzerinformationen basierend auf dem Token abzurufen.

Beispielsweise bietet der OAuth2-Anbieter SoundCloud eine solche URL. Wenn Sie einen OAuth2-Token für SoundCloud haben, können Sie eine GET-Anfrage an https://api.soundcloud.com/me?oauth_token=A_VALID_TOKEN senden und erhalten ein JSON-Objekt mit Informationen über den Benutzer.

Um dies in Discourse zu konfigurieren, müssen wir den Wert der Einstellung oauth2_user_json_url festlegen. In diesem Fall geben wir folgenden Wert ein:

https://api.soundcloud.com/me?oauth_token=:token

Der Teil mit :token weist Discourse an, diesen Wert durch den Autorisierungstoken zu ersetzen, der bei Abschluss der Authentifizierung empfangen wurde.

Es gibt noch einen letzten Schritt. Wir müssen Discourse mitteilen, welche Attribute im empfangenen JSON verfügbar sind. Hier ist eine Beispielantwort von SoundCloud:

{
  "id": 3207,
  "permalink": "jwagener",
  "username": "Johannes Wagener",
  "uri": "https://api.soundcloud.com/users/3207",
  "permalink_url": "http://soundcloud.com/jwagener",
  "avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848",
  "country": "Germany",
  "full_name": "Johannes Wagener",
  "city": "Berlin"
}

Die Variablen oauth2_json_user_id_path, oauth2_json_username_path, oauth2_json_name_path und oauth2_json_email_path sollten so gesetzt werden, dass sie auf die entsprechenden Attribute im JSON zeigen.

Das einzige erforderliche Attribut ist die id – wir benötigen diese, um bei zukünftigen Anmeldungen des Benutzers das richtige Konto abrufen zu können. Die anderen sind sehr hilfreich, falls verfügbar – sie beschleunigen den Registrierungsprozess für den Benutzer, da diese Felder im Formular automatisch ausgefüllt werden.

So habe ich die JSON-Pfad-Einstellungen konfiguriert:

  oauth2_json_user_id_path: 'id'
  oauth2_json_username_path: 'permalink'
  oauth2_json_name_path: 'full_name'

Ich habe permalink verwendet, da dies Discourses Erwartung für einen Benutzernamen näher kommt als der username im JSON. Beachten Sie, dass ich den E-Mail-Pfad weggelassen habe: SoundCloud stellt keine E-Mail-Adresse bereit, sodass der Benutzer diese bei der ersten Registrierung auf Discourse angeben und verifizieren muss.

Wenn die gewünschten Eigenschaften Ihres JSON-Objekts verschachtelt sind, können Sie Punkte verwenden. Wenn die API beispielsweise eine andere Struktur zurückgibt wie:

{
  "user": {
    "id": 1234,
    "email": {
      "address": "test@example.com"
    }
  }
}

könnten Sie user.id für oauth2_json_user_id_path und user.email.address für oauth2_json_email_path verwenden.

Enthält der Schlüssel selbst Punkte, müssen Sie ihn in doppelte Anführungszeichen setzen oder die Punkte mit einem Backslash escapen. Zum Beispiel, gegeben dieses JSON:

{
  "example.com/uid": "myuid"
}

würden Sie den Pfad als example\.com/uid oder "example.com/uid" angeben.

:warning: Wenn Sie oauth2_json_email_path setzen, muss der OAuth2-Anbieter bestätigen, dass der Benutzer diese E-Mail-Adresse besitzt. Unterlassung hiervon kann zu einer Übernahme des Kontos in Discourse führen!

:discourse2: Von uns gehostet? Dieses Plugin ist in unseren Business- und Enterprise-Plänen verfügbar. OAuth 2.0 & OpenID Connect Support | Discourse - Civilized Discussion

:spiral_notepad: Müssen Sie Benutzerregistrierungen automatisieren? Siehe Auto-provisioning user accounts when SSO is enabled

28 „Gefällt mir“
Keycloak with Discourse
Discourse SSO with OAuth2
Login from another user database
Shopify Integration
How can we enable Auth0 SSO in Discourse
OAuth2 integration with Drupal
OAuth connection of discourse
Login flow (Flask -> Discourse -> Flask) with OAuth
How to use Oauth2 service provided by discourse?
How to login to discourse from external website
Is "partial" SSO possible?
Set up Salesforce auth using OAuth2 basic support plugin
How to force users link phone number when they using Discourse?
OAuth2 Custom Redirects Plugin
Custom Login / Registration from another API
Login on discourse using mastodon credentials
Open source will support customized provider SSO
Oauth2 with fusionauth cert issues
Auto-provisioning user accounts when SSO is enabled
Configure sign up and log in with Auth0 using the OAuth2 Basic Plugin
SSO with TownNews CMS
What is supposed to go in “DISCOURSE_HOST”?
Custom Provider log-in with OAuth only sign-up/log-in
Discord, Google and Microsoft login, is oAuth2 enough?
Populating email field on login page
CodeBerg support
Gate our community to just members of our Shopify site?
Intergrate Discourse with keycloak
Integration into custom auth system where emails are not unique?
Twitter login doesn't work on meta
Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)
Question about Docker Manager?
Discourse OpenID Connect (OIDC)
🧩 How to Build an Android App User Community with Discourse? [HeyApks Project]
Bundling more popular plugins with Discourse core
Drupal 8 and Discourse shared SSO
Discourse for self hosting
Discourse + Intercom (Current User Id)
Error during SSO integration - Wholistic Minds
ADFS Authentication
Pulling user auth0 sub from OAuth2.0 plugin
Suggestion for improving Integrated Authentication development
Github and Twitter Login/Sign-Up Functionality?
Automatically creating a user when logging in with Webflow/Memberspace
Switching out authentication for a passwordless alternative
Removing Yahoo login from Core, and deprecating OpenID 2.0
Shopify Integration
SSO and Auth0
Migrate a Jive Clearspace forum to Discourse

Hallo,
wir versuchen, Discourse mit unserer Anwendung über OAuth2 Basic zu integrieren, erhalten aber die folgende Fehlermeldung in den Protokollen:
Hinweis: Wir verwenden NGROK zum Debuggen der Verbindung.

OAuth2 Debugging: request POST https://formshare.ngrok.io/oauth2/token

Headers: {"User-Agent"=>"Faraday v1.9.3", "Content-Type"=>"application/x-www-form-urlencoded", "Authorization"=>"Basic S2k2SFZtTVpuSTFHUExiRXVlWVJDNENiOkNvb1k0anlQemt3dWNRV21Sa2FWOVNnbHZLbjJFT3cxc3BIMmtMck9yY21vNDM4Tg=="}

Body: {"client_id"=>"Ki6HVmMZnI1GPLbEueYRC4Cb", "client_secret"=>"...some_secret_...", "grant_type"=>"authorization_code", "code"=>"5pPCrsp0pZ84373MNaHh2cuskfc8AlbfmdwMBFIVW4n4z9aX", :redirect_uri=>"https://community.formshare.org/auth/oauth2_basic/callback"}

------------------

OAuth2 Debugging: response status 200

From POST https://formshare.ngrok.io/oauth2/token

Headers: {"content-length"=>"108", "content-type"=>"text/html; charset=UTF-8", "date"=>"Thu, 01 Sep 2022 21:42:08 GMT", "ngrok-trace-id"=>"79cdc3f1c3eae5e37a30796aebbf9bd6", "server"=>"gunicorn"}

Body: {"token_type": "Bearer", "access_token": "p0FVuwjSXL1ZINEklMAVqUlpZxSll1SgnbpE8YWP4C", "expires_in": 864000}

-----------------------------------

(oauth2_basic) Authentication failure! invalid_credentials: OAuth2::Error, {"token_type": "Bearer", "access_token": "p0FVuwjSXL1ZINEklMAVqUlpZxSll1SgnbpE8YWP4C", "expires_in": 864000}

Wir haben die Parameter „oauth2 callback user id path“ und „oauth2 callback user info paths“ leer gelassen.

Jeder Hinweis ist willkommen.

Kann ich dies zur Authentifizierung mit dem XBL-Dienst von Microsoft verwenden?

Ich vermute, die Logik wäre ähnlich wie diese?

Hallo zusammen. Ich versuche, dieses Plugin mit unserem internen Oauth2-Server mit dem Autorisierungscode-Flow zu konfigurieren.

Wenn ein Benutzer auf „Mit Oauth verbinden“ klickt, funktioniert der /authorize-Endpunkt und ein Code wird an den Callback zurückgegeben. Aber dann zeigt Discourse einen generischen 500-Fehler „Oops. Die Software, die dieses Diskussionsforum antreibt, hat ein unerwartetes Problem festgestellt“ und der /token-Endpunkt wird nicht aufgerufen.

Das Fehlerprotokoll sagt Folgendes:
OAuth2::ConnectionError (FinalDestination: alle aufgelösten IPs waren nicht zulässig) lib/final_destination/ssrf_detector.rb:74:in lookup_and_filter_ips' lib/final_destination/http.rb:13:in connect’ lib/midd

Hostname discourse-app
process_id 653
application_version 702f27e6ee10ac257f5fee3f331d05f5fa5d7a45
HTTP_HOST *****
REQUEST_METHOD GET
HTTP_USER_AGENT Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
HTTP_REFERER *****
HTTP_X_FORWARDED_FOR *****
HTTP_X_REAL_IP *****
time 22:25 Uhr
params
code def50200babf84f7376f99fefa34369d876566b6bc0a341d8fba431999a72549ac06f6aad01df6fa43061707c525ba5d725ad
state 20139e0a134a5972566d4ddb9e5216973a

Nach meinem Verständnis gibt es ein Problem mit einer IP-Adresse? Derzeit ist der Oauth2-Server in meiner Entwicklungsumgebung (localhost) gehostet und die Endpunkte für Autorisierung und Token sind entsprechend konfiguriert. Ist das ein Problem?

Problem gefunden:

  1. Aus irgendeinem Grund wurde der Endpunkt /token nie aufgerufen. Nachdem die maximalen Optionen in den Admin-Parametern im Zusammenhang mit OAuth gesetzt wurden, wurde der Endpunkt ohne Antwort aufgerufen.
  2. Ich vergaß, dass der Discourse-Server und nicht der Webclient den Endpunkt /token aufrufen würde. Daher konnte der Server meinen lokalen Oauth2-Server nicht erreichen. Das Problem wurde behoben, indem unser Oauth2-Server hinter einer Domain platziert wurde.

Jetzt kann ich bestehende Benutzer verbinden, verstehe aber nicht, wie neue Benutzer über dieses Plugin angemeldet werden können.
Wenn sich der Benutzer mit OAuth anmeldet, erhält er eine Fehlermeldung, dass er kein aktives Konto auf dem Discourse-Server hat. Was normal ist, da es sich um einen neuen Benutzer handelt.

Gibt es einen dedizierten Callback, um den Benutzer anstelle der Anmeldung anzumelden? Oder einen bestimmten Parameter, der gesetzt werden muss, um die Kontoerstellung zu ermöglichen?

Mein Unternehmens-OAuth-Server generierte eine /profile-JSON-Antwort mit einem kleinen Tippfehler in einem Feld. Nachdem der Tippfehler behoben war, war alles in Ordnung.
Aber ich muss sagen, dass Discourse-Protokolle sehr irreführend sein können! Mit dem Callback war nichts falsch.

Hallo Team,

Ich habe ein Problem beim Abrufen der ID, die ich für meine Benutzer-JSON-Anfrage aus der Autorisierungsantwort benötige. Wenn ich die Dokumentation lese, scheint es, dass die Konto-ID in einem verschachtelten Array gesendet wird:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"Bearer",
   "expires_in":1800,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "permissions":[
      {
        "accountId":123,
        "availableScopes":["contacts_view", "contacts_me", 
"contacts_edit", "finances_view", "events_view"]
      }
   ]
}

Ich habe versucht, den OAuth2-Callback-Benutzer-ID-Pfad auf permissions[0].accountId zu setzen, aber mein UID-Wert ist immer leer. Leider erfordern Aufrufe zum Abrufen des Benutzer-JSON diese accountId in der JSON-URL.

Ich konnte dies zum Laufen bringen, indem ich permissions.first.accountId übergab. Ich stellte fest, dass, wenn ich permissions in eine Testeigenschaft übergab, das Array bereits als Ruby-Array geparst wurde. Leider lehnen die Felder die Ruby-Syntax zum Aufrufen von Array-Elementen ab, und jeder Versuch, Javascript-Syntax zu verwenden, würde zu einem TypeError String to Integer führen. Glücklicherweise hatte Ruby die obige Syntax. Ist dies die vorgesehene Methode?

Ich habe das gerade mit Authentik OAuth2 zum Laufen gebracht, allerdings gab es einige Schwierigkeiten mit der Einstellung oauth2 user json url. Ich habe den user_info-Endpunkt von Authentik dafür verwendet (/application/o/userinfo/), wusste aber nicht, wie ich die Felder zuordnen sollte. Für alle, die Discourse mit Authentik’s OAuth2 einrichten möchten, hier ist die Zusammenfassung:

  • User id path: preferred_username
  • Username path: preferred_username
  • Name path: name
  • Email path: email
  • Email verified path: email_verified
  • Avatar: leer.

Ich hatte folgende Probleme:

  1. Am Anfang habe ich den abschließenden Schrägstrich in der JSON-URL https://DOMAIN/application/o/userinfo/ vergessen. Dies führte dazu, dass die Benutzerinformationsanfrage (Permalink zum Quellcode) einen HTTP-Code 301 zurückgab, was zum Fehlschlag der Anmeldung führte. Ich weiß nicht, ob der abschließende Schrägstrich laut Spezifikation vorhanden sein sollte, aber vielleicht wäre es gut, 301 korrekt zu behandeln.
  2. Das Debugging erwies sich als schwierig. Die Einstellung oauth2 debug auth war eine Rettung, aber… Logster kürzt das Debug-Protokoll, bevor die aussagekräftigen Antwortdaten tatsächlich ausgegeben werden. Ich musste die Protokollzeile im Container manuell ändern zu
    log("user_json_response: #{user_json_response.status} #{user_json_response.headers} #{user_json_response.body}")
    
    Vielleicht könnte diese Protokollzeile aktualisiert werden? Ich denke, das könnte anderen Leuten helfen, die JSON-Attributpfade zu ermitteln.
4 „Gefällt mir“

Ich habe Auth0 gerade mit dem Plugin eingerichtet und festgestellt, dass Avatare nicht übernommen werden.

Dies sind die relevanten Einstellungen:

  DISCOURSE_OAUTH2_ENABLED: true
  DISCOURSE_OAUTH2_CLIENT_ID: '${DISCOURSE_OAUTH2_CLIENT_ID}'
  DISCOURSE_OAUTH2_CLIENT_SECRET: '${DISCOURSE_OAUTH2_CLIENT_SECRET}'
  DISCOURSE_OAUTH2_AUTHORIZE_URL: '${DISCOURSE_OAUTH2_ISSUER}/authorize?connection=xxx&login_options=yyy'
  DISCOURSE_OAUTH2_TOKEN_URL: '${DISCOURSE_OAUTH2_ISSUER}/oauth/token'
  DISCOURSE_OAUTH2_USER_JSON_URL: '${DISCOURSE_OAUTH2_ISSUER}/userinfo'
  DISCOURSE_OAUTH2_SCOPE: 'email openid profile'
  DISCOURSE_OAUTH2_JSON_USER_ID_PATH: 'sub'
  DISCOURSE_OAUTH2_JSON_USERNAME_PATH: 'nickname'
  DISCOURSE_OAUTH2_JSON_NAME_PATH: 'name'
  DISCOURSE_OAUTH2_JSON_EMAIL_PATH: 'email'
  DISCOURSE_OAUTH2_JSON_EMAIL_VERIFIED_PATH: 'email_verified'
  DISCOURSE_OAUTH2_JSON_AVATAR_PATH: 'picture'
  DISCOURSE_OAUTH2_EMAIL_VERIFIED: true
  DISCOURSE_OAUTH2_OVERRIDES_EMAIL: true
  DISCOURSE_OAUTH2_ALLOW_ASSOCIATION_CHANGE: false

Im Debug-Log sehe ich, dass das picture-Element im JSON-Response gesetzt ist, aber der Avatar des Benutzers ändert sich nicht, weder für neue noch für bestehende Benutzer.

Was habe ich übersehen?

Was ist der beste Weg, das Symbol auf der Anmeldeschaltfläche durch ein anderes Symbol oder ein Bild zu ersetzen?

.btn-social.oauth2_basic:before {
    content: url('https://www.contoso.com/path/to/image');
}

.btn-social.oauth2_basic > svg {
    display: none;
}

fühlt sich ausreichend, aber ein wenig hacky an

2 „Gefällt mir“

Es scheint, dass das Plugin den Avatar/Benutzernamen nur bei der erstmaligen Erstellung des Benutzers aktualisiert, nicht aber jedes Mal, wenn er sich anmeldet.

Gibt es eine Möglichkeit, dies zu beheben und das Plugin auch beim Anmelden/Wiederverbinden den Avatar aktualisieren zu lassen?

Sie können die Einstellungen auth overrides email, auth overrides username und auth overrides name verwenden, damit diese bei zukünftigen Anmeldungen gelten. Ich fürchte, wir haben derzeit keine ähnliche Einstellung für Avatare, aber es wäre pr-welcome

2 „Gefällt mir“

Danke! Ich habe diese später tatsächlich gefunden. Ich habe das Repository geforkt und meine eigenen Versionen hinzugefügt, um es mit Roblox zum Laufen zu bringen, einschließlich des Overrides für Avatare. Was, glaube ich, nur den DiscourseConnect Avatar-Override verwendet, damit die Leute ihn nicht ändern können.

Eine Sache, die ich mir wünsche, ist, dass Roblox keine E-Mail bei OAuth bereitstellt, daher muss ich sie leider mit einer E-Mail registrieren lassen. Aber das ist für euch kein Problem, haha.

Ein Beitrag wurde in ein neues Thema aufgeteilt: Twitter-Login funktioniert nicht auf Meta

Weiß jemand, ob das noch funktioniert?

Ja. Ich bin zuversichtlich, dass dieses Plugin funktioniert. :+1:

1 „Gefällt mir“

Hallo, ich konnte dieses Plugin in mein Discourse discuss.frontendlead.com integrieren. Ich verwende Teachable OAuth https://docs.teachable.com/docs/oauth-quickstart-guide

Ich möchte jedoch nur zulassen, dass sich Personen erfolgreich registrieren können, wenn sie ein aktuelles bezahltes Konto bei Teachable haben. Ich stelle mir vor, dass ich benutzerdefinierte Funktionalität in das Plugin einbauen muss, um dies zu handhaben? Ich frage mich, ob Sie oder auch ich ein weiteres Feld in den Einstellungen namens „Custom Code“ nach OAuth einführen können, das es Entwicklern ermöglicht, nach der Anmeldung spezifische Aktionen durchzuführen? Oder wenn es bessere Vorschläge gibt, lassen Sie es mich bitte wissen.

Bearbeiten: Ich habe das Repository geforkt und hier zum Laufen gebracht:

Wenn jemand anderes Teachable verwendet und dasselbe versucht, funktioniert mein Repository sofort. Das Einzige ist, wenn Sie keinen Kurs gekauft haben, wird angezeigt, dass Sie zu meiner Domain gehen müssen, um ihn zu kaufen. Möglicherweise möchten Sie dies für Ihren eigenen Anwendungsfall aktualisieren.

2 „Gefällt mir“

Das ist großartig!

Es gibt eine ähnliche Situation mit der OAuth2-Registrierung mit dem Discourse Patreon-Plugin. Wenn „Mit Patreon anmelden“ aktiviert ist, können sich alle mit einem Patreon-Konto auf der Discourse-Website registrieren. Was Website-Besitzer im Allgemeinen wollen, ist, nur ihren Unterstützern die Registrierung von Discourse-Konten zu ermöglichen. Ich frage mich, ob Details von Patreon zurückgegeben werden, die es ermöglichen würden, eine ähnliche Logik zur Patreon-Authentifizierung hinzuzufügen?

1 „Gefällt mir“

Ich habe genau den gleichen Fehler wie @qlands oben.

Mein ursprünglicher Plan war, die Profilinformationen im Token zu senden. Da dies nicht funktionierte, habe ich es reduziert, um den JSON-Ansatz zu versuchen. Aber es kommt nicht einmal dazu, die JSON-Datei aufzurufen.

Die Fehlermeldung lautet:

(oauth2_basic) Authentifizierungsfehler! ungültige Anmeldeinformationen: OAuth2::Error, {
  "access_token":"fa79b6fe0763862f5a8fd8",
  "token_type":"Bearer",
  "expires_in":3600,
  "scope":"profile"
}

Sehen Sie etwas Falsches an der obigen Antwort?
Warum würde das Plugin einen Fehler bei ungültigen Anmeldeinformationen generieren, während der OAuth2-Server mit einem Token mit 200 geantwortet hat?