Synchroniser les données utilisateur DiscourseConnect avec la route sync_sso

L’authentification unique (Single Sign-On) peut être utilisée pour gérer l’authentification des utilisateurs Discourse à partir d’un site distinct. Le sujet Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) contient des détails sur la mise en œuvre de DiscourseConnect.

Le problème

Avec DiscourseConnect, les utilisateurs Discourse sont créés ou mis à jour lorsqu’ils se connectent à Discourse depuis votre site externe. Ce qui n’est pas géré, c’est le cas où vous devez créer ou mettre à jour des utilisateurs Discourse sans qu’ils aient à se connecter à votre site. Pour les sites utilisant DiscourseConnect, ces cas doivent être traités en effectuant une requête POST authentifiée vers la route sync_sso.

:information_source: Si vous utilisez le gem Discourse API, vous pouvez utiliser la méthode sync_sso du gem au lieu du code suivant. Consultez le répertoire examples pour des instructions sur l’utilisation de cette méthode.

À titre d’exemple, prenons le cas où un utilisateur est ajouté à un groupe sur le site parent et doit être ajouté au groupe correspondant sur Discourse sans avoir à se connecter d’abord avec DiscourseConnect. Le nom du groupe sur le site et sur le forum est « eurorack ». L’external_id de l’utilisateur est 1 et son adresse e-mail est bob@example.com. Le code suivant utilise PHP. L’idée de base peut être appliquée à n’importe quel langage de programmation.

Configurer vos identifiants API et votre clé secrète SSO

$api_key = '4fe83002bb5fba8c9a61a65e5b4b0a3cf8233b0e4ccafc85ebd6607abab4651a';
$api_username = 'system';
$discourse_connect_secret = 'jdhb19*Xh3!nu(#k';

Configurer les paramètres SSO

Pour voir quels paramètres sont disponibles, consultez la section ACCESSORS de discourse_connect_base.rb. Le paramètre que vous devez inclure pour mettre à jour un utilisateur existant est external_id. Si vous appelez sync_sso pour un utilisateur qui n’existe pas encore sur Discourse, vous devez inclure les paramètres username et email. Discourse utilisera username et email pour créer un nouvel utilisateur.

Pour ajouter un utilisateur à un groupe, incluez le paramètre add_groups. Pour supprimer un utilisateur d’un groupe, incluez le paramètre remove_groups. La valeur de l’un ou l’autre de ces paramètres doit être une chaîne de noms de groupes séparés par des virgules. Les espaces ne sont pas autorisés entre les noms de groupes.

:information_source: Le paramètre require_activation est inclus dans le payload. Il doit être défini sur true si l’e-mail de l’utilisateur n’a pas été validé sur le site parent. Avec PHP, le paramètre doit être défini sur la chaîne ‘true’ pour éviter qu’il ne soit converti en nombre 1. Si vous avez validé l’adresse e-mail de l’utilisateur, vous n’avez pas besoin d’inclure ce paramètre.

// Créer un tableau de paramètres SSO.
$sso_params = array(
    'external_id' => 1,
    'email' => 'bob@example.com',
    'username' => 'bob',
    'add_groups' => 'eurorack',
    'require_activation' => 'true',
);

// Convertir les paramètres SSO en payload SSO et générer la signature SSO.
$sso_payload = base64_encode( http_build_query( $sso_params ) );
$sig = hash_hmac( 'sha256', $sso_payload, $discourse_connect_secret );

Envoyer la requête POST

Pour cet exemple, j’utilise curl, définis le user_agent sur ‘WordPress/4.9.4’ et l’URL du forum sur 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 ) {
    // Gérer l'erreur, appeler curl_close( $ch ) et retourner.
}

curl_close( $ch );

$discourse_user = json_decode( $result );

Mise à jour des utilisateurs existants

Les requêtes envoyées à la route sync_sso mettent à jour les propriétés des utilisateurs existants de la même manière que si l’utilisateur s’était connecté au site avec DiscourseConnect. Cela signifie que les valeurs des paramètres du site auth overrides et discourse connect overrides de votre site seront respectées pour ces requêtes. Par exemple, pour mettre à jour l’adresse e-mail des utilisateurs existants via des requêtes à sync_sso, le paramètre auth overrides email doit être activé. Voici les paramètres pertinents :

  • auth overrides email
  • auth overrides username
  • auth overrides name
  • discourse connect overrides avatar
  • discourse connect overrides bio
  • discourse connect overrides groups
  • discourse connect overrides profile background
  • discourse connect overrides card background
  • discourse connect overrides location
  • discourse connect overrides website

Pour aller plus loin

Pour voir ce qui se passe, consultez le code sync_sso, la méthode parse de DiscourseConnectBase, et la méthode lookup_or_create_user de DiscourseConnect.

Il existe également une version JavaScript de ce guide pour ceux qui utilisent Node.js.

32 « J'aime »
Sync DiscourseConnect user data with the sync_sso route [JavaScript]
/admin/users/sync_sso ... Route not found
SSO_SYNC not working
Using the API to create a user on an SSO only system
SSO integration & external profile sync help
Creating Discourse accounts via SSO without visiting the forum URL?
Sync_sso post suddenly resulting in 404 not found after succesfully adding a portion of the users
Changing avatar_url while sso_overrides_avatar is set?
"push" sso users to discourse?
Groups API - manually syncing group membership?
SSO_SYNC not working
PHP/API to check whether user exists (by email) and is in specific group
Pre-create user accounts for SSO users
User profile page by id?
DiscourseConnect Provider Questions
Logging in discourse using API - using discourse as API server only
I cannot add user to the discouse forum from a wordpress website when user added in a membership
Integration into custom auth system where emails are not unique?
:cn: Synchronizing DiscourseConnect user data using sync_sso [Java] | 使用 sync_sso 同步 DiscourseConnect 用户数据 [Java]
Letting users choose whether to show Full Name
Auto-provisioning user accounts when SSO is enabled
Creating Discourse accounts during user import
Refresh sso groups
/admin/users/sync_sso 403 Forbidden
Triggering automatic authentication via SSO when linking to private topics?
"BAD CSRF" when executing PUT using API, curl, and PHP
Delete user avatar by API
Delete user avatar by API
Help me troubleshoot my Discourse SSO
Adding existing (and inviting new) users to a group
Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)
DiscourseConnect, SSO and E-Mail address confirmation
AUTOMATIC: Inviting every new SaaS signup into the Discourse Forum
Question necromancy: migrating from mattermost
Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)
How to "intercept" first time SSO usages to let users confirm the SSO action and set a username?
API Create user external_ids parameter
First time login for a user using API KEY
How to use Discourse Connect (SSO) to update avatar, username, name?
How to set language for SSO users
What are your experiences with wp-discourse plugin and DiscourseConnect?

Je reçois ce message : {"failed":"FAILED","message":"Erreur de connexion"}