Single Sign-On kann verwendet werden, um die Discourse-Benutzerauthentifizierung von einer separaten Website aus zu verwalten. Das Thema unter Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) enthält Details zur Implementierung von DiscourseConnect.
Das Problem
Mit DiscourseConnect werden Discourse-Benutzer erstellt oder aktualisiert, wenn sie sich von Ihrer externen Website aus bei Discourse anmelden. Was jedoch nicht abgedeckt wird, ist der Fall, in dem Sie Discourse-Benutzer erstellen oder aktualisieren müssen, ohne dass sie sich auf Ihrer Website anmelden. Für Sites, die DiscourseConnect verwenden, sollten diese Fälle durch eine authentifizierte POST-Anfrage an die Route sync_sso behandelt werden.
Wenn Sie die Discourse-API-Bibliothek (Gem) verwenden, können Sie stattdessen die Methode
sync_ssodes Gems nutzen. Im Verzeichnis examples finden Sie Anweisungen zur Verwendung dieser Methode.
Als Beispiel betrachten wir den Fall, dass ein Benutzer auf der übergeordneten Site zu einer Gruppe hinzugefügt wird und er ohne vorherige Anmeldung mit DiscourseConnect zu einer entsprechenden Gruppe auf Discourse hinzugefügt werden muss. Der Name der Gruppe ist sowohl auf der Website als auch im Forum ‘eurorack’. Die external_id des Benutzers ist 1 und seine E-Mail-Adresse lautet bob@example.com. Der folgende Code verwendet PHP. Das Grundprinzip lässt sich auf jede Programmiersprache übertragen.
Einrichten Ihrer API-Anmeldedaten und des SSO-Geheimnisses
$api_key = '4fe83002bb5fba8c9a61a65e5b4b0a3cf8233b0e4ccafc85ebd6607abab4651a';
$api_username = 'system';
$discourse_connect_secret = 'jdhb19*Xh3!nu(#k';
Einrichten der SSO-Parameter
Um zu sehen, welche Parameter verfügbar sind, werfen Sie einen Blick auf den Abschnitt ACCESSORS in discourse_connect_base.rb. Der Parameter, den Sie zwingend angeben müssen, um einen bestehenden Benutzer zu aktualisieren, ist external_id. Wenn Sie sync_sso für einen Benutzer aufrufen, der noch nicht auf Discourse existiert, müssen Sie die Parameter username und email angeben. Discourse verwendet username und email, um einen neuen Benutzer zu erstellen.
Um einen Benutzer zu einer Gruppe hinzuzufügen, geben Sie den Parameter add_groups an. Um einen Benutzer aus einer Gruppe zu entfernen, geben Sie den Parameter remove_groups an. Der Wert für beide Parameter muss als durch Kommas getrennte Zeichenfolge von Gruppennamen festgelegt werden. Zwischen den Gruppennamen sind keine Leerzeichen erlaubt.
Der Parameter
require_activationist im Payload enthalten. Dieser sollte auftruegesetzt werden, wenn die E-Mail-Adresse des Benutzers auf der übergeordneten Site noch nicht validiert wurde. BeiPHPmuss der Parameter auf den String ‘true’ gesetzt werden, damit er nicht in die Zahl1umgewandelt wird. Wenn Sie die E-Mail-Adresse des Benutzers bereits validiert haben, müssen Sie diesen Parameter nicht angeben.
// Erstellen Sie ein Array mit SSO-Parametern.
$sso_params = array(
'external_id' => 1,
'email' => 'bob@example.com',
'username' => 'bob',
'add_groups' => 'eurorack',
'require_activation' => 'true',
);
// Konvertieren Sie die SSO-Parameter in den SSO-Payload und generieren Sie die SSO-Signatur.
$sso_payload = base64_encode( http_build_query( $sso_params ) );
$sig = hash_hmac( 'sha256', $sso_payload, $discourse_connect_secret );
Senden der POST-Anfrage
Für dieses Beispiel verwende ich curl, setze den user_agent auf ‘WordPress/4.9.4’ und die Forum-URL auf https://forum.example.com.
$url = 'https://forum.example.com/admin/users/sync_sso';
$post_fields = array(
'sso' => $sso_payload,
'sig' => $sig,
);
$headers = array("Content-Type: multipart/form-data;","Api-Key: $api_key","Api-Username: $api_username",);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $post_fields ) );
curl_setopt( $ch, CURLOPT_USERAGENT, 'WordPress/4.9.4' );
$result = curl_exec( $ch );
if ( curl_errno( $ch ) !== 0 ) {
// Fehler behandeln, curl_close( $ch ) aufrufen und zurückkehren.
}
curl_close( $ch );
$discourse_user = json_decode( $result );
Aktualisierung bestehender Benutzer
Anfragen an die Route sync_sso aktualisieren Eigenschaften bestehender Benutzer auf die gleiche Weise, als ob der Benutzer sich mit DiscourseConnect auf der Site angemeldet hätte. Das bedeutet, dass die Werte der Site-Einstellungen auth overrides und discourse connect overrides für diese Anfragen berücksichtigt werden. Um beispielsweise die E-Mail-Adresse bestehender Benutzer mit Anfragen an sync_sso zu aktualisieren, muss die Einstellung auth overrides email aktiviert sein. Hier sind die relevanten Einstellungen:
auth overrides emailauth overrides usernameauth overrides namediscourse connect overrides avatardiscourse connect overrides biodiscourse connect overrides groupsdiscourse connect overrides profile backgrounddiscourse connect overrides card backgrounddiscourse connect overrides locationdiscourse connect overrides website
Weiterführende Literatur
Um zu sehen, was im Hintergrund passiert, werfen Sie einen Blick auf den sync_sso-Code, die DiscourseConnectBase-parse-Methode und die DiscourseConnect-lookup_or_create_user-Methode.
Es gibt auch eine JavaScript-Version dieses Leitfadens für diejenigen, die Node.js verwenden.