Tutorial : authentification SSO avec OpenID (en PHP)
12 January 2009 par Dimitri HoOpenID est un protocole ouvert permettant une authentification unique à travers plusieurs sites (aussi appelé « Single-Sign-On », SSO). On évite ainsi d'avoir à gérer un couple identifiant/mot de passe pour chaque site nécessitant un enregistrement.
Cet article a pour but d'expliquer son fonctionnement et d'intégrer ensuite une authentification en PHP avec la bibliothèque PHP OpenID de JanRain.
Fonctionnement
Avant d'entrer dans le fonctionnement, voici les termes que je vais utiliser dans la suite de l'article :
- RP : « Relying Party » ou « Consumer », le site qui veut vérifier l'identité de l'utilisateur.
- OP : « OpenID Provider », le site qui fournit les identifiants OpenID et qui authentifie un utilisateur.
- MAC : « Message Authentication Code », une fonction de hash comme MD5 ou SHA1 par exemple, mais dépendant d'une clé secrète.
- Un utilisateur demande à s'authentifier chez le RP. Il entre un identifiant (qui peut être l'URL de l'OP ou son identifiant personnel). Exemple d'identifiant :
foo.myopenid.com. - À partir de l'identifiant fourni, le RP en déduit l'adresse de l'OP (protocole Yadis).
- Il établit un contact avec l'OP afin de partager une clé MAC. Cette étape est optionnelle, mais elle permet de réduire plus tard les échanges entre ce RP et cet OP. Cette clé a une durée de vie fixée par l'OP, et est réutilisable pour de futures connexions.
- Le RP redirige l'utilisateur vers son OP, en fournissant en GET ou en POST l'URL vers laquelle l'OP devra renvoyer l'utilisateur.
- L'utilisateur s'authentifie (ou est déjà authentifié) chez son OP. Ici, l'utilisateur peut choisir les données à renvoyer au RP, son identité, etc. C'est un détail d'implémentation qui n'est pas couverte par la spécification OpenID.
- L'OP renvoie l'utilisateur vers le consommateur grâce à l'adresse fournie en 4, avec en GET ou en POST les informations concernant l'identité de l'utilisateur. Le tout est signé avec un MAC. Ces informations sont uniques et ne peuvent être utilisées qu'une seule fois. Pour cela, le RP peut soit en garder une trace, soit en limiter le temps de validité puisqu'elles sont datées.
- Le RP vérifie enfin que les données renvoyées sont authentiques. Pour cela, s'il possède une clé commune grâce à l'étape 3, il peut vérifier la signature. Sinon, il doit renvoyer toutes les informations à l'OP, lequel confirmera leur authenticité.
Avantages
- L'utilisateur ne s'authentifie qu'une seule fois chez le fournisseur OpenID, et peut se retrouver authentifié sur d'autres sites sans avoir à retaper son mot de passe.
- Champs préremplis : il est possible de créer différents profils chez le fournisseur, et de choisir quel profil et quelles informations peuvent être renvoyées au consommateur. On gagne ainsi énormément de temps pour les formulaires.
- Contrairement à d'autres systèmes SSO, il existe plusieurs fournisseurs, et on peut même créer son propre serveur.
- Ce système ne repose que sur HTTP/1.1, et est donc compatible avec les plus anciens navigateurs.
Inconvénients
- Un seul site détient toutes les informations concernant les profils d'un utilisateur, les sites visités, etc. L'utilisateur est donc particulièrement vulnérable sur ce point. Pour les plus paranoïaques, MyOpenID.com tente de renforcer la sécurité en proposant une authentification plus forte via l'utilisation de certificat et/ou de code de confirmation envoyé par SMS.
- OpenID en est encore à ses débuts. Malgré son adoption par les acteurs majeurs du web, la plupart d'entre eux restent à l'état de fournisseurs OpenID.
PHP OpenID Library
C'est une implémentation du protocole en PHP. Elle fournit une API pour créer un OP ou un RP. Nous allons nous intéresser ici à la partie « consumer ».
Création d'un compte OpenID
Tout d'abord, commencez par vous créer un identifiant OpenID, si ce n'est déjà fait. Vous pouvez vous inscrire sur myopenid.com. Si vous avez déjà un compte Google ou Yahoo, vous possédez déjà un identifiant OpenID. Pour un compte Google, il suffit d'entrer « https://www.google.com/accounts/o8/id » sur le champ identifiant.
Configuration
Tout ce qu'il vous faut pour ce tutoriel, c'est un serveur avec PHP, accessible de « l'extérieur » de préférence. Aucune extension n'est nécessaire. Créez un dossier OpenIDConsumer et rajoutez-y le dossier Auth de la bibliothèque PHP OpenID.
Créez un fichier const.php dans lequel nous mettrons quelques constantes :
- REALM : l'URL qui identifie votre serveur.
- RETURN_TO : l'URL pointant vers le script qui fera la vérification.
- STORAGE : dossier où stocker les clés MAC (dossier hors du DocumentRoot de préférence...)
Formulaire de connexion
Créez un fichier login.php, et insérez un formulaire pour la connexion, avec la méthode GET ou POST, au choix. Ici j'ai utilisé la méthode POST.
Dans le fichier qui réceptionnera l'identifiant (ici, c'est toujours login.php), commencez par ouvrir une session.
On définit ensuite comment seront stockées les clés. Pour simplifier les choses, j'ai choisis ici le mode fichier avec la classe Auth_OpenID_FileStore, mais on peut bien évidemment utiliser des bases de données avec Auth_OpenID_MySQLStore par exemple.
On crée ensuite un objet Auth_OpenID_Consumer.
La méthode begin prend en argument l'identifiant entré par l'utilisateur.
Dans la ligne 18, on spécifie les données que l'on souhaite récupérer du serveur. Le premier argument de build signifie que l'on a réellement besoin du pseudonyme de l'utilisateur. Le nom complet et l'email sont optionnels. Ces champs sont définis par une extension à OpenID, OpenID Simple Registration Extension. Le caractère optionnel ou non ne garantit en tout cas pas que le serveur va effectivement renvoyer ces données. En général, l'utilisateur est d'abord prévenu par l'OP.
On arrive ensuite sur redirectURL. Le premier argument, REALM, indique l'identifiant du serveur. Il peut contenir un métacaractère (wildcard, l'étoile) au début. Il est utilisé par l'OP notamment pour stocker les clés partagées avec le RP. Le RETURN_TO spécifie l'URL vers lequel l'utilisateur sera renvoyé une fois authentifiée chez l'OP. Le RETURN_TO doit « correspondre » au REALM ou appartenir à une sous-arborescence du REALM. Par exemple, *.quux.fr et foo.quux.fr/verif.php correspondent. Dans le cas contraire l'OP renverra une erreur.
Remarque : évitez d'avoir un REALM trop vaste, comme *.free.fr. Cela signifie que quiconque possédant un site perso chez Free pourra récupérer la clé que vous partagez avec l'OP, et par conséquent usurper l'identité de tous les utilisateurs gérés par cet OP sur votre site.
Enfin, on redirige l'utilisateur vers l'OP sur la ligne 23.
Vérification
À la réception, il ne reste presque plus rien à faire. Il faut à nouveau créer un Auth_OpenID_Consumer et invoquer la méthode complète qui fera la vérification. On affiche ensuite les résultats renvoyés.
Sources du tutorial
Sources
- Schéma du protocole OpenID : blog de Bernie Thompson
- Spécifications d'OpenID : OpenID.net
Tags: authentification, consumer, openid, php, single sign on, sso, unique



