Problème SSO : paramètres SSO ou SIG manquants

Salut, j’ai un problème avec Discourse SSO. Qu’est-ce que je fais mal ? Mon code ci-dessous extrait d’autres plateformes sans problème. Cependant, je n’obtiens aucun nonce.


// Activer la journalisation des erreurs pour le débogage
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Charger le fichier d'initialisation
require_once '/init.php'; // Mettez à jour ce chemin en fonction de la configuration de votre plateforme

// Clé secrète Discourse Connect et URL pour renvoyer la charge utile
$sso_secret = 'keyhere'; // Remplacez par votre clé secrète partagée Discourse
$discourse_url = 'https://urlhere.com/session/sso_login'; // Remplacez par votre URL Discourse

// Démarrer la session pour vérifier l'état de connexion de l'utilisateur de la plateforme
session_start();

// Vérifier si l'utilisateur est connecté
if (!isset($_SESSION['uid'])) {
    // Si l'utilisateur n'est pas connecté, rediriger vers la page de connexion de la plateforme
    header('Location: /clientarea.php');
    exit;
}

// Débogage : journaliser les paramètres de la requête entrante
error_log("Paramètres GET reçus : " . print_r($_GET, true));

// Vérifier si nous avons reçu les paramètres 'sso' et 'sig' de Discourse
if (!isset($_GET['sso']) || !isset($_GET['sig'])) {
    error_log("Paramètres SSO ou SIG manquants.");
    header('Location: /clientarea.php');
    exit;
}

// Valider la signature SSO à l'aide de la clé secrète
$sso = $_GET['sso'];
$sig = $_GET['sig'];
$expected_sig = hash_hmac('sha256', $sso, $sso_secret);

if ($sig !== $expected_sig) {
    error_log("Signature SSO invalide. Attendu : $expected_sig, Reçu : $sig");
    header('Location: /clientarea.php');
    exit;
}

// Récupérer les détails du client de la plateforme
$clientDetails = localAPI('getclientsdetails', ['clientid' => $_SESSION['uid']], 'admin');
if ($clientDetails['result'] !== 'success' || !isset($clientDetails['userid'])) {
    error_log("Échec de la récupération des détails du client de la plateforme.");
    header('Location: /clientarea.php');
    exit;
}

// Extraire les détails de l'utilisateur
$userId = $clientDetails['userid'];
$email = $clientDetails['email'];
$firstName = $clientDetails['firstname'];
$lastName = $clientDetails['lastname'];
$username = $firstName . ' ' . $lastName;

// Décoder la charge utile SSO
$sso_payload = base64_decode($sso);
parse_str($sso_payload, $sso_params);

if (!isset($sso_params['nonce'])) {
    error_log("Le nonce est manquant dans la charge utile SSO.");
    header('Location: /clientarea.php');
    exit;
}

// Préparer la charge utile SSO de retour avec les détails de l'utilisateur
$return_payload = [
    'nonce' => $sso_params['nonce'],
    'email' => $email,
    'external_id' => $userId,
    'username' => $username,
    'name' => $firstName . ' ' . $lastName,
    'admin' => 0, // Mettre à 1 si l'utilisateur est un administrateur, sinon laisser à 0
    'moderator' => 0 // Mettre à 1 si l'utilisateur est un modérateur, sinon laisser à 0
];

// Encoder la charge utile de retour en Base64
$query_string = http_build_query($return_payload);
$encoded_payload = base64_encode($query_string);

// Signer la charge utile encodée avec la clé secrète Discourse
$return_sig = hash_hmac('sha256', $encoded_payload, $sso_secret);

// Débogage : journaliser la charge utile et la signature
error_log("Charge utile de retour : " . print_r($return_payload, true));
error_log("Charge utile encodée : $encoded_payload");
error_log("Signature de retour : $return_sig");

// Rediriger vers Discourse avec la charge utile signée
header("Location: $discourse_url?sso=" . urlencode($encoded_payload) . "&sig=" . urlencode($return_sig));
exit;

Journaux d’erreurs :

[25-Sep-2024 14:50:17 UTC] Paramètres SSO ou SIG manquants.
[25-Sep-2024 14:53:59 UTC] Paramètres GET reçus : Array
(
[sso] => nonce_from_discourse
)

[25-Sep-2024 14:53:59 UTC] Paramètres SSO ou SIG manquants.

Je ne suis pas sûr pourquoi ?

Je ne sais pas non plus. DiscourseConnect est-il configuré sur votre site Discourse ? Comment les utilisateurs arrivent-ils à l’URL gérée par ce code ?

Passer par le processus d’authentification avec l’inspecteur de votre navigateur ouvert sur son onglet Réseau pourrait donner des détails sur ce qui se passe.

Merci pour votre réponse.

J’essaie d’intégrer avec WHMCS. J’ai tout configuré correctement dans le code et les paramètres activés dans Discourse.

J’obtiens une partie de la réponse mais il manque la signature (sig). Je pensais que cela pourrait être une erreur de décodage car il semble y avoir une divergence entre les deux systèmes.

Ce n’est pas vraiment ma spécialité, je fais de mon mieux pour assembler les pièces mais je me gratte la tête depuis deux jours. Je ne vois pas mon erreur.

J’ai essayé autant de débogages que possible, j’ai reconstruit Discourse. Journalisation étape par étape. J’ai essayé ChatGPT. J’ai comparé avec le code du plugin WordPress. Bloqué.

Il semble probable que quelque chose ne soit pas configuré correctement. Essayez peut-être de prendre un peu de recul. Je n’ai pas de site fournisseur SSO configuré sur mon installation locale pour le moment, mais cela pourrait vous aider en partie.

Sur Discourse, assurez-vous que les paramètres suivants sont configurés :

Le paramètre discourse connect url doit être défini sur l’URL qui gère le code que vous avez posté.

Définissez le paramètre discourse connect secret sur une chaîne de caractères d’au moins 10 caractères. Notez que vous avez la chaîne de 7 caractères keyhere codée en dur dans le code que vous avez posté. Je suppose que vous modifiez cette valeur lorsque vous exécutez le code. Définissez-la sur la même valeur que celle que vous avez entrée sur Discourse.

Maintenant, déconnectez-vous de votre site Discourse. Ouvrez l’inspecteur web de votre navigateur dans l’onglet réseau. Cliquez sur le bouton “Login” sur Discourse. Vous devriez voir des requêtes similaires aux deux premières requêtes de la capture d’écran ci-dessous :

La première requête sera vers http://forum.example.com/session/sso?return_path=%2F

La requête suivante devrait être vers https://example.com/?sso=<payload_sso_envoyé_par_discourse>&sig=<signature_sso>

example.com et forum.example.com doivent être définis sur les domaines réels que vous utilisez.

Si tout est configuré correctement, je m’attendrais à ce que cela attribue les valeurs des paramètres sso et sig aux variables que vous avez définies ici :

$sso = $_GET['sso'];
$sig = $_GET['sig'];

Si c’était moi, je commenterais probablement le reste du code et je me contenterais de confirmer que vous pouvez recevoir la charge utile et l’attribuer aux variables.

Avec DiscourseConnect activé, vous pouvez vous reconnecter à votre site Discourse en visitant la route /u/admin-login. Si vous avez accès à la console Rails du site Discourse, vous pouvez également vous reconnecter en désactivant DiscourseConnect depuis la console Rails :

SiteSetting.enable_discourse_connect = false

Il est possible qu’il y ait des erreurs plus loin dans le code que vous avez posté. Par exemple, je pense que vous devez appeler urldecode sur la valeur du paramètre sso avant de générer le sig attendu. Regardez comment le plugin WP Discourse le gère :

$payload dans la fonction ci-dessus n’est que la valeur du paramètre de requête sso, après qu’il ait été assaini ici : wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

1 « J'aime »