SPIP - Contrib

[ar] [en] [es] [fr] [it]



Accueil du site > Auteurs et Authentification > Authentification > OpenID

Plugin d’authentification OpenID

lundi 2 avril 2007, par elafargue. Dernier ajout jeudi 29 mars 2007


Ce plugin permet à SPIP d’accepter OpenID comme méthode d’authentification des rédacteurs.

Si vous êtes familier avec OpenID, sautez à la section « guide d’utilisateur », sinon lisez le reste !


A propos d’OpenID

OpenID pour l’utilisateur

OpenID (voir http://openid.net/ est un système d’authentification dite « fédérée » ou « décentralisée », c’est à dire qu’il permet à un utilisateur de choisir un « fournisseur d’identité » (en anglais un IDP, Identity Provider) unique. Ensuite, s’il souhaite accéder à un site web compatible OpenID, il lui suffit d’indiquer à ce site le nom de son IDP auquel le site (en anglais RP, Relying Party) déléguera la tâche d’authentifier l’utilisateur. Une explication très claire (mais en anglais) est dispo sur openidenabled.com.

Concrètement, voici à quoi cela correspond comme expérience utilisateur :
- Alice souhaite s’identifier sur exemple.com. Exemple.com lui propose d’utiliser son OpenID
- Alice entre son URI OpenID (sous la forme http://alice.myopenid.com) dans le champ de login de exemple.com
- exemple.com redirige Alice (via son navigateur web) vers myopenid.com
- Alice indique à myopenid.com si elle accepte de fournir ou non son identité à exemple.com.
- Alice redirigée vers exemple.com et est maintenant logguée.

Des intérêts multiples pour l’utilisateur

Vous me demanderez « mais à quoi cela peut-il servir? ».

Hé bien les intérêts sont multiples pour l’utilisateur : tout d’abord, il n’a plus besoin de créer des dizaines de profils sur des dizaines de sites différents, il lui suffit d’avoir un profil unique sur un IDP pour accéder à tout site supportant OpenID. Si on est identifié sur son IDP, on accède immédiatement à tous les sites compatibles sans se réauthentifier, c’est le principe du « Single Sign On ».

Ensuite, cela permet de ne confier ses infos perso (en particulier son mot de passe!) qu’à un seul site auquel on fait confiance : en effet, les sites consommateurs d’OpenID (les RP) ne connaissent que l’OpenID de l’utilisateur, rien de plus, puisque toute l’authentification est déléguée à l’IDP.

Pour élargir le débat, ce type d’authentification décentralisée est ces derniers temps au coeur des discussions sur la nature de l’identité numérique et sa gestion. En effet, ces systèmes ont la particularité d’être, a mon sens pour la première fois, des systèmes de gestion de l’identité qui améliorent la protection de la vie privée, en plaçant l’utilisateur au coeur de la transaction, plutôt que de lui demander de confier à tous ses interlocuteurs des informations personnelles pour tout et n’importe quoi. OpenID (et les autres systèmes de la même famille) permet de choisir à qui l’on fait confiance pour lui donner ses informations d’identité, c’est une amélioration appréciable, ou en d’autres termes, l’inverse de la tendance « Big brother »... .

Pour en savoir plus

Cependant, SPIP-Contrib n’est pas un lieu de discussion autour des enjeux de l’identité numérique, il y a des sites excellents qui en parlent, si vous voulez en savoir plus :
- Identity 2.0 : LA référence sur le sujet, avec des présentations absolument lumineuses de Dick Hardt sur l’identité numérique à l’heure du Web 2.0. Note pour les allergiques au marketing : dépassez votre allergie pour 5 minutes, allez voir par vous-mêmes, çela ouvre des perspectives.
- OpenID.net : le site qui pointe vers toute la sphère OpenID, un point de passage obligé.
- MyOpenID.com : si vous voulez vous créer un OpenID, ce site vous en propose, c’est gratuit, c’est parfait pour tester.
- OpenIDenabled : ensuite, pour développer, ce site est une bonne ressource.

Et le plugin, dans tout cela?

Effectivement : encore une fois, je ne veux pas lancer de discussion enflammée autour des mérites des schémas d’authentification fédérée par rapport à http_auth, ce n’est pas le lieu. L’objectif de cet article est de proposer un plugin qui implémente OpenID pour SPIP, ensuite, au webmestre de choisir s’il en veut ou non !

Approche légère

Un des aspects sympathiques d’OpenID est qu’on peut en général utiliser son propre site web comme identifiant OpenID (oui, un OpenID se présente sous la forme d’un URL, par exemple : http://edouard.lafargue.name/). Les profils utilisateurs de SPIP permettant déjà d’entrer l’adresse de son site web, c’est ce champ qui sera utilisé par le plugin. Comme cela, on évite de surcharger SPIP.

Mécanisme de l’authentification OpenID

Pour faire simple : un site qui souhaite authentifier un utilisateur avec un OpenID récupère l’OpenID en question, et lance l’authentification proprement dite, en redirigeant l’utilisateur vers son IDP, et en fournissant à l’IDP l’adresse de retour sur le site où renvoyer l’utilisateur après authentification réussie (ou non). En option, le site peut demander à l’IDP des informations supplémentaires sur l’utilisateur, comme adresse email, âge, ou toute autre précision. L’IDP demandera alors à l’utilisateur s’il l’autorise à communiquer ces éléments au site ou non. Encore une fois, voir openidenabled pour plus de détails.

Identification dans SPIP

Dans SPIP, la cinématique d’authentification est la suivante : SPIP affiche le formulaire de login, qui fait la demande d’identifiant et boucle sur lui-même. Lors du second affichage, le formulaire demande le mot de passe, et passe alors la main à l’action « cookie » qui tout d’abord essaie d’authentifier l’utilisateur d’abord en MySQL puis avec LDAP s’il est actif, et ensuite appelle les fonctions ad-hoc internes de SPIP pour créer une session et écrire son cookie dans le navigateur. L’utilisateur est alors redirigé vers la page d’acceuil si tout s’est bien passé, ou bien renvoyé sur la page de login.

Pour supporter OpenID, il faut donc intervenir à deux endroits : le formulaire de login, pour détecter qu’un URL a été entré et prendre l’action qui va bien pour lancer l’authentification OpenID, puis l’action « cookie » qui doit être adaptée pour ajouter la méthode d’authentification OpenID, c’est à dire le traitement du résultat de l’authentification renvoyé par l’IDP.

Idéalement, il suffirait d’ajouter une méthode d’authentification dans l’action « cookie » à la suite de LDAP, mais SPIP à l’heure actuelle (1.9.1) n’a pas de point d’entrée pour ajouter des méthodes d’authentification génériques, ce qui conduit à alourdir un peu l’implémentation et la rendre plus sensible (lire fragile) face aux évolutions de SPIP.

Le plugin fonctionne donc en surchargeant les mécanismes suivants dans SPIP :
- La balise #LOGIN_PUBLIC, pour détecter un URL dans le champ login et prendre l’action nécessaire
- Le formulaire de login pour indiquer qu’on peut entrer un OpenID
- Enfin, il fournit une action « cookie_openid » pour traiter le résultat de l’authentification OpenID. Cela permet de ne pas toucher à l’action « cookie » original et préserver les méthodes d’authentification natives de spip.

En pratique, si le formulaire de login public détecte un URL OpenID, il lance l’authentification sur l’IDP. Si l’URL ne fonctionne pas (faute de frappe etc), le formulaire affiche l’erreur et reboucle. Sinon, il passe l’action « cookie_openid » à l’IDP comme point de retour après authentification auprès de l’IDP.

Et le code?

Tout est sur la Zone dans les plugins de dev, sous-répertoire « authentification », c’est à dire . Installez sur votre Spip (testé sur 1.9.1, pas sur 1.9.2 encore), activez, et ça doit marcher direct. Pour plus de commodité, j’ai mis un tar gz dans cet article.

Attention : ce plugin contient les librairies PHP OpenID JainRain version 1.2.2 (merci Fil!). Si ces libs sont déjà installées sur votre serveur, vous pouvez les retirer du plugin.

Guide d’utilisateur

- Installez le plugin et activez-le
- Dans votre profil d’auteur, indiquez votre URL OpenID dans le champ de l’URL votre site web.
- Déconnectez-vous. Effacez les cookies Spip de votre navigateur pour éviter des effets de bords indésirables.
- Le formulaire de login doit avoir un peu changé (videz le cache si nécessaire) et proposer "Identifiant ou bien OpenID". Entrez votre URL OpenID :

- Spip vous redirige vers votre IDP, authentifiez-vous :

Dans l’exemple ci-dessus, l’utilisateur est déjà loggué sur MyOpenID : le site ne lui demande donc pas son mot de passe, mais si il accepte la demande d’authentification de « ed-vero.com ». Si il clique sur « allow forever », à chaque fois qu’il utilisera son OpenID sur ed-vero.com, il sera identifié instantanément dans interaction — visible pour l’utilisateur — avec MyOpenID.

- Si tout s’est bien passé... vous êtes renvoyé vers SPIP et authentifié !

Notes : l’authentification par identifiant et mot de passe n’est pas désactivée, afin de ne pas risquer de bloquer son accès à SPIP en cas de problème sur l’IDP. Ce plugin propose l’utilisation d’OpenID en plus et non à la place des méthodes habituelles.

Evolutions futures/possibles

- Vérification que l’utilisateur possède bien l’OpenID quand il édite son profil.
- « nice to have » mais pas critique en matière de sécurité, pourquoi un utilisateur indiquerait-il un OpenID appartenant à quelqu’un d’autre ?
- En option, possibilité de désactiver le login/mot de passe pour les visiteurs si l’on souhaite qu’ils utilisent uniquement OpenID
- Enregistrement automatique des visiteurs si ils n’existent pas dans SPIP et fournissent un OpenID
- Signature des commentaires avec OpenID.
- D’autres suggestions ?


Répondre à cet article

  • Plugin d’authentification OpenID

    4 avril 2007 12:24, par LG

    En fait, on peut passer par l’action cookie orifinal de SPIP. Elle n’est pas surchargeable, mais elle appelle la méthode d’authentification interne de SPIP, qui elle est surchrageable.

    voici un exemple de surcharge possible :

    function inc_auth_spip($login, $pass)
    {
            if (__est_un_login_OpenId($login))
            {
                    // verifier ici l'authentification OpenID
                   
                    if (__est_bien_un_login_OpenId_valide_et_authentifier($login))
                    {
                            // chercher l'auteur dans la base
                            $result = spip_query("SELECT id_auteur FROM spip_auteurs WHERE url=" . _q($login) . " AND statut<>'5poubelle'");
                            $row = spip_fetch_array($result);
                            if (!$row) // pas d'auteur correspondant
                            {
                                    // on peut le creer automatiquement avec la fonction message_inscription
                                    $commentaire = message_inscription($email, $nom, 'redac', 0);
                                    // et lui envoyer un message de bienvenue (que l'on peut aussi personnaliser)
                                    if (function_exists('envoyer_inscription'))
                                            $f = 'envoyer_inscription';
                                    else
                                            $f = 'envoyer_inscription_dist';
                                    $commentaire = $f($commentaire, $nom, $mode, $id);
                                    // et pourquoi pas allez faire des modifs specifiques sur l'auteur
                            }
                           
                            $result = spip_query("SELECT * FROM spip_auteurs WHERE url=$login"); // par exemple
                            $row = spip_fetch_array($result);
                            return $row;
                    }
                    else // pas valide
                    {
                                    spip_log("proxy user creation canceled: ".$commentaire);
                                    return array();
                    }
            }
            else // sinon, methode standard
            {
                    include_spip('inc/auth_spip');
                    return inc_auth_spip_dist ($login, $pass);
            }
    }

    A+

    Répondre à ce message

    • Plugin d’authentification OpenID 4 avril 2007 14:30, par Fil

      Peux-tu faire ce changement directement dans le plugin ? S’il est sur la zone, c’est justement fait pour ça :)

      Répondre à ce message

      • Plugin d’authentification OpenID 4 avril 2007 15:54, par LG

        C’est juste que j’ai pas trop le temps là...

        Ceci dit, j’ai extrait cet exemple d’un plugin que j’ai réalisé pour mettre des SPIP en extranet derrière un serveur unique IIS jouant le role de reverse proxy et validant l’accès sécurisé. Les spips derrières le reverse proxy autenthifient automatiquement l’utilisateur selon les infos fournies par le reverse proxy (c’est bien du SSO - avec sécurité déportée sur un autre système - ici privé) et prennent en compte le fait que leur propre url (celle utilisée par le reverse proxy) est différente de l’url vue de l’utilisateur finale (qui est celle du reverse proxy).

        Si ça peut intéresser quelqu’un, j’en pourrai en faire, quant j’aurai 3 secondes (sic), un plugin documenté, ou au moins une documentation de conception.

        A+,

        Répondre à ce message

    • Plugin d’authentification OpenID 8 avril 2007 19:42, par elafargue

      J’avais bien voulu faire les choses comme cela au début, mais en fait, c’est l’action cookie qui dispatche entre les authent LDAP, Base ou autres. Et d’autre part, lors d’une authent OpenID, Spip doit lancer l’authentification dès la saisie du login, avant d’avoir un mot de passe.

      Mais effectivement, il serait bon que Spip puisse supporter l’insertion d’autres méthodes d’authent plus facilement dans son code...

      Répondre à ce message

      • Oui, c’est bien l’action cookie qui dispatche entre les différents types d’authentification. Dans mon cas (SSO derrière un reverse-proxy qui assure aussi l’authentification), j’ai mis dans le mes_options d’un plugin dédié la surcharge de inc/auth_spip et l’algorithme suivant (qui s’exécute donc à chaque appel de page) :

        if (_on_est_dans_un_cas_valide_d_authentification_automatique)
        {
         if ($auteur_session) // si on a une session spip valide
         {
           if (_la_session_spip_ne_correspond_pas_a_l_authentification) // on ne sait jamais
           {
             $auteur_session = '';
           }
         }
         if (!$auteur_session && !$essai_login) // si on a pas de session spip valide et on n'est pas en train d'en initier une via l'action cookie
         {
           include_spip('action/cookie');
           $url = $_SERVER['HTTP_X_PUBLIC_HOST'].$GLOBALS['REQUEST_URI'];
             // c'est ce qui marche dans mon cas - plus généralement, le code de inc / utils / url_de_base() donne de quoi se débrouiller
           $cible = str_replace('&','&',$url);
           $post = parametre_url(generer_url_action('cookie','essai_login=oui',true),'url',$cible,'&');
           include_spip('inc/headers');
           redirige_par_entete($post);
         }
         elseif ($auteur_session)
         {
           // on est dans une session valide, on peut faire des choses comme initialiser des variables de contexte de session utilisables dans les squelettes pour les particulariser
         }
        }

        Ca doit pouvoir fonctionner aussi pour ton plugin.

        A+, LG

        Répondre à ce message

    Retour au début des forums

  • Plugin d’authentification OpenID

    5 avril 2007 19:42, par marabbeh

    Super, j’en révais d’un truc comme ça ! Bon je vais regarder ces infos à fond.

    Répondre à ce message

    Retour au début des forums



Suivre la vie du site RSS 2.0 | Plan du site | Espace privé | Charte et fonctionnement SPIP-Contrib | SPIP | L'autre.net