Configuration d’une authentification SAML en PHP

Authentification SAML côté client

Ce tutoriel est un guide qui vous permettra de mettre en place une authentification via le protocole SAML avec la librairie SimpleSAMLphp. Nous explorerons les étapes détaillées pour mettre en place l’authentification côté client. Nous ne verrons pas la configuration coté serveur.

Dans le contexte de l’authentification SAML, le client, souvent appelé Service Provider (SP), communique avec l’Identity Provider (IdP). Cette communication est établie au moyen de messages SAML échangés entre le SP et l’IdP. Ces messages, généralement encapsulés dans des requêtes HTTP, permettent le transfert sécurisé des assertions d’identité et des informations d’authentification.

Plus précisément, lorsqu’un utilisateur tente d’accéder à une ressource protégée par le SP, ce dernier redirige l’utilisateur vers l’IdP pour l’authentification. Une fois authentifié, l’IdP génère une assertion SAML contenant des informations sur l’identité de l’utilisateur. Cette assertion est ensuite renvoyée au SP, qui la vérifie pour autoriser l’accès.

La communication entre le SP et l’IdP s’appuie généralement sur des protocoles web standard tels que HTTP/HTTPS. Les messages SAML, souvent basés sur XML, sont échangés conformément aux spécifications du protocole SAML, assurant ainsi une communication sécurisée et fiable lors du processus d’authentification unique (SSO).

Les fichiers clés de la librairie

Avant tout, la librairie se trouve à cet endroit. Depuis le dossier racine de la librairie, nous devons configurer les fichiers suivants :

  • Dossier_racine ➞ config ➞ authsources.php
  • Dossier_racine ➞ cert ➞ pem.crt
  • Dossier_racine ➞ cert ➞ pem_private.crt
  • Dossier_racine ➞ cert ➞ pem_idp.pem
  • Dossier_racine ➞ metadata ➞ saml20-idp-remote.php

Avant de configurer ces fichiers nous allons créer les fichiers suivants du projet

  • auth.php ➞ Il permet de déclencher l’authentification
  • callback.php ➞ C’est le fichier qui permet de consommer le jeton SAML renvoyé par IdP autrement dit le serveur.
  • mon_app.php ➞ Ce sera le fichier qui contiendra votre application quand l’utilisateur aura passé et réussit l’authentification.

auth.php

<?php

//////////////////////// AUTHENTIFICATION SAML ////////////////////////
require_once('../lib/simplesamlphp-2.0.5/src/_autoload.php');
//Initialise SimpleSAMLphp
$as = new SimpleSAML\Auth\Simple('default-sp');
// Authentification de l'utilisateur
$as->requireAuth();

callback.php

// Démarrer une session PHP
session_start();

// Inclure la bibliothèque SimpleSAMLphp
require_once('../lib/simplesamlphp-2.0.5/src/_autoload.php');

// Décodez la réponse SAML reçue en base64 depuis un formulaire POST
$samlResponseXML = base64_decode($_POST['SAMLResponse']);

// Créer un objet SimpleXMLElement à partir de la réponse SAML
$xml = new SimpleXMLElement($samlResponseXML);

// Convertir l'objet SimpleXMLElement en JSON pour une manipulation plus facile
$jsonData = json_encode($xml);
$data = json_decode($jsonData, true);

// Extraire les informations d'assertion du tableau JSON
$assertion = $data["Assertion"]["AttributeStatement"]["Attribute"];

// Décommenter la ligne suivante pour afficher le contenu de //l'assertion, à vous d'adapter cette ligne en debuggant le json pour //voir sa construction à coup de :
// var_dump($assertion);

// Extraire des attributs spécifiques de l'assertion SAML, dans mon cas // je récupère les données suivantes fournies par l'IdP
$prenom = $assertion[5]["AttributeValue"];
$nom = $assertion[6]["AttributeValue"];
$user_id = $assertion[7]["AttributeValue"];

// Vérifier si les informations extraites ne sont pas vides
if(!empty($prenom) && !empty($nom) && !empty($user_id)){
// Stocker les informations dans la session PHP
$_SESSION['data_saml'][0] = $prenom.$nom.$user_id;
$_SESSION['data_saml']['prenom'] = $prenom;
$_SESSION['data_saml']['nom'] = $nom;
$_SESSION['data_saml']['user_id'] = $user_id;

// Rediriger l'utilisateur vers une autre page après une authentification réussie
header("Location: https://votre_domaine.fr/dossier_racine/mon_app.php");
exit;
}

Ci-dessus le callback.php a stocké des données en session. Ce sont les données que le serveur a fourni une fois l’authentification réussit. Dans notre application soit le fichier mon_app.php vous avez maintenant la possibilité de récupérer les données du serveur en appelant ces variables de sessions que vous exploiterez comme bon vous semblera. Voici à quoi doit ressembler le début du fichier mon_app.php

mon_app.php

// Démarrer une session PHP
session_start();
// Récupérer les données de sessions
$prenom = $_SESSION['data_saml']['prenom'];
$nom = $_SESSION['data_saml']['nom'];
$user_id = $_SESSION['data_saml']['user_id'];

// Maintenant commencez votre application en exploitant les données de sessions...

saml20-idp-remote.php

<?php

/**
* Métadonnées distantes IdP SAML 2.0 pour SimpleSAMLphp.
*
* N'oubliez pas de supprimer les IdPs que vous n'utilisez pas de ce fichier.
*
* Voir : https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote
*/
$metadata['https://sts.windows.net/xxxx-0c7a-459xxxxxxxxa48xxxx/'] = [

// URL du service Single Sign-On (Connexion unique)
'SingleSignOnService' => 'https://login.microsoftonline.com/xxxx-0c7a-459xxxxxxxxa48xxxx/saml2',

// URL du service Single Logout (Déconnexion unique)
'SingleLogoutService' => 'https://login.microsoftonline.com/xxxx-0c7a-459xxxxxxxxa48xxxx/saml2',

// Chemin du certificat utilisé pour la communication sécurisée
'certificate' => 'pem_idp.pem'

];

Noter bien que le fichier ci-dessus spécifie le chemin du certificat utilisé pour sécuriser la communication avec l’IdP. Ce certificat est à récupérer auprès du serveur IdP ainsi que l’url de SingleSignOnService et SingleLogoutService. Le contenu entre crochets (['https://sts.windows.net/xxxx-0c7a-459xxxxxxxxa48xxxx/']) pourrait être un nom générique ou symbolique plutôt qu’une URL spécifique. Cependant, dans la pratique, il est généralement recommandé d’utiliser l’URL de l’Identity Provider (IdP) pour garantir une configuration précise et éviter les confusions.

Les certificats

Nous venons de voir l’emplacement où il est nécessaire de spécifier le chemin vers le certificat de l’Identity Provider (IdP) dans la bibliothèque Simplesamlphp.. Il aurait également été possible d’inclure directement le certificat à cet endroit, mais personnellement, je pense que regrouper les trois certificats dans un même dossier demeure la meilleure solution.

Maintenant, il est essentiel d’acquérir votre propre certificat. Vous avez la possibilité de le générer gratuitement auprès de votre hébergeur. Par exemple, avec Let’s Encrypt si vous disposez de cette option, ou de l’acheter auprès de fournisseurs disponibles en ligne. Une fois que vous l’avez obtenu et configuré sur votre nom de domaine, copiez-collez la clé publique du certificat de votre application dans le fichier pem.crt et la clé privée dans le fichier pem_private.crt.

Voici un exemple de certificat

-----BEGIN CERTIFICATE-----
MIICpDCCAYwCCQCeYU7eR9RxfDANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCTUExFDASBgNVBAcMC0NoaW5hLCBIZXlkb2UxDzANBgNVBAoM
BkV4YW1wbGUxETAPBgNVBAsMCEluZGl2aWR1YWwxDTALBgNVBAMMBHRlc3QxIjAg
Fw0yMjA0MTQxNjI5MDdaGA8yMTIxMDMxMjE2MjkwN1owDTELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAk1BMQ4wDAYDVQQHDAVDaGljYTEOMAwGA1UECgwFRXhhbXBsZTER
MA8GA1UECwwISW5kaXZpZHVhbDENMAsGA1UEAwwEdGVzdDEiMCAGCSqGSIb3DQEJ
ARYTYm9iQGV4YW1wbGUuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAK2ZLXuX
yimVL87euPXcGvLbLy1yU1+u+VOYP+eVG8Ck55YBm6Hz/Dl1fRke6NUFtR45gDil
B4zfADrkNKkCAwEAATANBgkqhkiG9w0BAQsFAANBAK1DjY7bQUVUSnhU8CdLoqZD
zRFDAtZkX5h+lgv5ijJ6sY2RdBupnC3ZKuxEG+dTH1pbCkgqlQ0pM6DC4pZpJVE=
-----END CERTIFICATE-----

authsources.php

Dans ce fichier c’est default-sp qu’il faut modifier et adapter. ‘entityID’ spécifie l’ID d’entité unique de ce SP qui est l’url de votre nom de domaine de l’application qui héberge tous les fichiers que nous venons de voir. Puis vous retrouvez les chemins vers les certificats SSL de votre domaine. Enfin L’attribut 'idp' précise l’ID d’entité de l’IdP que le SP doit contacter. S’il est NULL ou non défini, l’utilisateur verra une liste d’IdPs disponibles pour choisir.


'default-sp' => [
'saml:SP',

// L'ID d'entité de ce SP.
'entityID' => 'https://votre_nom_de_domaine.fr/',

// Le certificat pour la communication sécurisée.
'certificate' => 'pem.crt',

// La clé privée correspondante au certificat.
'privatekey' => 'pem_private.crt',

// L'ID d'entité de l'IdP que ce SP devrait contacter.
// Peut être NULL/non défini, auquel cas l'utilisateur verra une liste d'IdPs disponibles.
//'idp' => 'https://sts.windows.net/xxxx-0c7a-459xxxxxxxxa48xxxx/'
];

Félicitations pour avoir suivi ce tutoriel ! Avec ces informations, vous disposez des éléments nécessaires pour mettre en place l’authentification SAML côté client. Pour la configuration côté serveur, vous trouverez aisément des ressources en ligne. Cet article a été rédigé en réponse aux défis rencontrés lors de la mise en œuvre de ce protocole dans le cadre de mon travail. En espérant que cela puisse vous faire gagner du temps.

N’hésitez pas à laisser un commentaire pour partager votre expérience ou poser des questions. Vos retours sont précieux et contribuent à améliorer la qualité de ce tutoriel. Merci de votre lecture et à bientôt !

Loading