Accueil > OpenID Connect OAuth Server par DnC > Développer > Ressources pour les développeurs

Extension OpenID Connect pour phpBB

  publié le par DnC

Un client OIDC pour phpBB. Permet à phpBB d’utiliser OpenID Connect au lieu de l’authentification classique. (Attention : à ne pas confondre avec les extension pour OpenID !)

Les développeurs d’application phpBB pourront faciliter l’intégration des forums dans leurs autres applications Web en permettant l’accès des utilisateurs avec une inscription unique configurée sur le serveur OIDC (Single Sign-On, SSO).

OAuthSD vous offre plus que l’inscription unique. La connexion unique (Single Login-In, SLI) : une fois connecté à une application, vous serez connecté de manière transparente aux autres (à condition bien sûr qu’elles soient enregistrées sur le serveur).

Prérequis

- phpBB 3.x
- système Linux + PHP 5.6 ou 7.1.
- Attention ! le fonctionnement d’OIDC exige une application cliente installée sur un serveur sécurisé (protocole https://).

Inscription sur le serveur OAuthSD

L’application recevant l’extension doit être enregistrée sur le serveur OAuthSD [1].
La procédure est décrite ici : OpenID Connect : Lier une application cliente au serveur OAuthSD.

En suivant cette procédure :
- vous vous inscrirez en tant qu’auteur sur le serveur,

- vous enregistrerez votre application. L’enregistrement se fait ici : Inscrire une application cliente.
Vous devrez :

  • configurer l’adresse de retour (Redirect URI) sous la forme suivante : https://mon_application.com/ucp.php?mode=login&login=external&oauth_service=oauthsd
  • Inscrire les scopes "openid sli".

Notez les valeurs de "Client id" (qui correspondra à "Key" dans phpBB) et "Client secret".

Installation et configuration sur phpBB

1. Le client OIDC pour phpBB s’installe comme toute extension de phpBB :
- télécharger l’extension OIDC client for phpBB (se trouve aussi sur GitHub),
- décompresser l’archive,
- installer le code dans /ext/bdegoy/oauthsd,
- dans phpBB, installez l’extension "DnC OIDC client for OAuthSD" (section Customize -> Extension Manager).

2. Installez le service OAuthSD pour Lusitanian / PHPoAuthLib :
phpBB utilise la bibliothèque Lusitanian / PHPoAuthLib pour mettre en œuvre le SSO avec OIDC. Nous devons compléter cette bibliothèque avec le service Oauthsd. Le service OAuthSD est fourni avec le fichier ... /oauthsd-phpbb/OAuth/OAuth2/Service/Oauthsd.php qui doit être copié dans le répertoire .../vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/.

3. dans phpBB, section Client Communication -> Authentication, sélectionnez la méthode d’authentification Oauth :

- Entrez les paramètres pour OAuthSD :

- puis actionnez le bouton "Submit".

Si tout s’est bien passé, un bouton "OAuthSD" doit apparaître dans la page de Connexion :

Notre prototype est visible à l’URL : https://phpbb.dnc.global/.

Notes :
- Le bouton "OAuthSD" n’apparait pas partout où la connexion est possible. Par exemple, on s’attendrait à voir le bouton sur la page de connexion à l’administration, mais ce n’est pas le cas. Cela dépend de phpBB [2], pas de l’extension.

phpBB : Tentative de connexion avec un compte inconnu du forum

Si on tente de se connecter avec un login (un "Nom d’utilisateur" dans le vocabulaire phpBB) qui n’est pas enregistré sur le forum, phpBB signale l’erreur :

il est proposé de :
- lier le compte à un compte existant : Entrer le Nom d’utilisateur et le Mot de passe puis actionner "Connexion" [3]
- créer un nouveau compte : Actionnez le bouton "S’enregistrer".

Notes :
- Seul le login (le Nom d’utilisateur) doit être identique des deux côtés, le mot de passe est propre à chaque système.
- On pourrait penser à une autre solution : inscrire le compte phpBB sur le serveur d’authentification. Mais cela irait à l’encontre du principe de connexion unique (SSO) : si un utilisateur a une inscription sur OAuthSD, c’est pour pouvoir se connecter à différents systèmes avec les mêmes identifiants.

Feuille de route

- Paramétrer l’URL du serveur OIDC afin de pouvoir choisir le serveur d’authentification. Cela devrait conduire à un client OpenID Connect universel.
- Essayer d’agir sur phpBB pour mieux intégrer l’authentification. Par exemple, l’insertion du bouton d’authentification sur la page de connexion ACL.

En conclusion ...

Cette inscription d’une application PhpBB montre qu’OAuthSD est bien un serveur d’authentification tout aussi accessible que les grandes plateformes. Mais avec OAuthSD nous vous offrons beaucoup plus : le moyen de protéger vos données et de protéger les visiteurs de vos sites à l’aide d’un serveur de votre propriété.

Notons que cette utilisation qui est faite d’OpenID Connect réduit le point de vue au SSO. OpenID Connect, c’est énormément plus que le SSO, qui n’en est qu’un aspect mineur.

OpenID Connect, c’est :
- la protection des mots de passe,
- la sécurisation des échanges entre applications réparties dans le Cloud,
- et, avec OAuthSD, la Connexion unique (Single Login-In, SLI)
etc.

Voyez :

https://area51.phpbb.com/docs/dev/3.2.x/extensions/tutorial_authentication.html

 On GitHub
https://github.com/bdegoy/oauthsd-phpbb
Issues (Bug reports or feature request) :
https://github.com/bdegoy/oauthsd-phpbb/issues

Notes

[1Dans l’état actuel du développement, l’extension ne permet que la connexion à ce serveur OAuthSD, cela n’est donc envisageable que dans une phase de développement. DnC propose à ses clients de posséder leur propre serveur OIDC afin de bénéficier de toute la sécurité offerte par un système d’authentification privé.

[2La connexion à l’aide d’un système extérieur n’est gérée que dans le script ucp.php (User Control Panel) mais pas dans acp.php (Admin Control Panel).

[3Si, ce faisant, vous liez l’utilisateur Oauth à un utilisateur phpBB qui avait déjà été lié, vous obtenez une erreur SQL du genre "Duplicate entry ’2-oauthsd’ for key ’PRIMARY’ [1062]", où "2" est l’ID de l’utilisateur phpBB . C’est un bug de phpBB qui devrait auparavant effacer l’entrée user_id = 2 dans la table phpbb_oauth_account. Si on efface manuellement cette entrée, on peut terminer l’opération.

Extension pour Wordpress "OpenID Connect Generic Client"

  publié le par DnC

Il existe différentes extensions de client OpenID Connect pour WordPress. Nous présentons ici OpenID Connect Generic Client de daggerhart qui nous parait complète, bien construite et bien documentée.

En cours de développement : un fork incluant le monitoring et le management de la session.


Installation

 L’extension peut être trouvée sur GitHub :
- https://github.com/daggerhart/openid-connect-generic,
- https://github.com/bdegoy/openid-connect-generic (notre fork).
Le plugin s’installe comme toute extension, de façon classique ou avec Composer. Voyez la documentation.

Notes :
- La source Github est mieux tenue à jour que celle du site WP (version testée jusqu’à 5.1.1 en mai 2019).

Inscription de l’application sur le serveur OAuthSD

Il s’agit des étapes 1 et 2 de la procédure décrite ici : OpenID Connect : Lier une application cliente au serveur OAuthSD.

S’inscrire en tant qu’auteur

En suivant cette procédure vous commencerez par vous inscrire en tant qu’auteur sur le serveur OAuthSD.

Inscrire l’application
Vous devez désigner votre application WordPress comme client du serveur OpenID Connect. Pour cela, accédez à l’URL : https://oa.dnc.global/web/?page=cre... :

- Client Id : Entrez un nom court, sans espace ni caractère spécial autre que ’_’. Ce n’est lié à aucune désignation de votre application.

- Client secret (obligatoire) : une courte chaîne assimilable à un mot de passe fort. Ce code doit rester secret.

- Redirect uri (obligatoire) : URI de retour à l’application cliente. Si l’URL de votre application WP est "http://votre_application.ext", inscrivez "http://votre_application.ext/wp-admin/admin-ajax.php?action=openid-connect-authorize.

- Grant Type (obligatoire) : sélectionnez "Authorization Code".

- Scopes (obligatoire) : Inscrivez "openid profile email".

Configuration de WP

Il s’agit de l’étape 3 de la procédure.

Accédez au menu Réglages -> OpenID Connect Client.

Votre application Wordpress doit être configurée comme ci-après, où Client ID et Client Secret Key sont les valeurs inscrites précédemment sur le serveur :

Inscription d’un utilisateur sur OAuthSD

Le principe de l’inscription unique (Single Sign On, SSO) permet à un utilisateur de se connecter à différentes applications avec les mêmes identifiants (login, mot de passe ...).
Il faut donc d’abord inscrire un utilisateur sur OAuthSD (ou utiliser un utilisateur OAuthSD existant). Faire l’inverse (créer l’utilisateur sur votre application WP et l’inscrire sur le serveur OpenID Connect) irait à l’encontre du principe.

L’inscription d’un utilisateur se fait ici : https://oa.dnc.global/web/spip.php?...

Création de l’utilisateur par WP

Si l’utilisateur n’existe pas du côté WP, l’extension le créera.

Notes :
- Si on tente de se loger avec un identifiant de l’utilisateur OIDC qui existe déjà pour un utilisateur WP, le plugin crée un utilisateur WP avec un identifiant incrémenté ; par exemple si le login est "admin", l’utilisateur WP d’identifiant "admin2" sera créé avec un rôle "abonné". Il appartiendra à l’administrateur du site WP de modifier éventuellement ce rôle.
- Dans le cas où l’e-mail de l’utilisateur OpenID existe déjà pour un utilisateur WP différent, c’est OpenID qui est maître : le plus logique sera de changer l’identifiant de cet utilisateur WP pour celui de l’utilisateur OpenID (puisque l’e-mail désigne une personne de façon non ambiguë).

Erreurs provenant de la configuration

- Missing state - La plupart du temps, cette erreur provient du fait que l’utilisateur a été trop long pour s’identifier, ou est retourné sur un formulaire ancien. Il suffit de recommencer.

- User claim incomplete - Se produit quand la liste des déclarations (claims) retournées par Userinfo, en fonction des portées définies pour l’application (scopes) ne contient pas celles qui sont définies dans le format.
Par exemple :

  • l’application a été configurée sans le scope email (champ de configuration OpenID Scope) et le format Email Formatting est email.
  • Display Name Formatting a été fixé à name alors que ce champ est null dans le serveur OpenID pour l’utillisateur considéré et que le nom de l’utilisateur figure dans la déclaration family_name.

- Failed user creation - Se produit le plus souvent quand WP tente de créer un nouvel utilisateur et que l’e-mail déclaré par l’utilisateur OIDC existe déjà du côté de WP.

- redirect_uri_mismatch : The redirect URI provided is missing or does not match - Cette erreur est générée par le serveur OAuthSD en réponse à la requête au contrôleur Authorize. Elle se produit lorsque l’URL de retour (Redirect URI) enregistrée sur le serveur OAuthSD n’est pas conforme à ce qui est indiqué en bas du formulaire Réglages -> OpenID Connect - Generic Client. En particulier, OAuthSD impose le protocole de transfert sécurisé (https).

- ERREUR : les cookies sont bloqués ou ne sont pas reconnus par votre navigateur. Vous devez activer les cookies pour utiliser WordPress. - Il est probable que vous ayez omis ’https://’ dans la barre d’adresse.

Erreur CORS (visible dans le debugger du navigateur
C’est une erreur très courante que de lancer l’application de test avec http:// au lieu de https://. Cela peut également conduirte à une erreur CORS :
"(index):1 Access to XMLHttpRequest at ’https://oa.dnc.global/authorize?response_type=code&client_id=wpdemo&user_id=wpadmin&state=124979a12478&scope=openid&prompt=none’ from origin ’http://wp.dnc.global’ has been blocked by CORS policy : The ’Access-Control-Allow-Origin’ header has a value ’https://wp.dnc.global’ that is not equal to the supplied origin."

Démonstration

https://wp.dnc.global/2019/05/11/ex... est un démonstrateur d’une application WP liée à OAuthSD avec cette extension.

Monitoring : développement en cours

Nous développons un fork qui inclut le monitoring.
 Le code est visible ici : https://github.com/bdegoy/openid-co.... Le fonctionnement est semblable à ce qui a été décrit pour Plugin OpenID Connect Client pour SPIP.

Plugin OpenID Connect Client pour SPIP

  (publié initialement le jeudi 3 janvier 2019) par DnC

Un client OIDC pour SPIP. Permet à une application SPIP de proposer l’authentification avec OpenID Connect, à côté de l’authentification classique.

Les développeurs d’application SPIP pourront renforcer la protection de l’accès aux fonctionnalités réservées et à l’espace privé en limitant l’accès aux seules personnes enregistrées sur le serveur OIDC configuré [1].

Prérequis

- v 1.0.3 : SPIP 3.0, 3.1 ; v 1.0.4 : SPIP 3.2,
- système Linux + PHP 5.6 ou 7.1,
- ionCube PHP Loader installé sur le serveur de l’application SPIP (IonCube est installé par défaut sur la plupart des configurations Linux).
- Attention ! le fonctionnement d’OIDC exige une application cliente installée sur un serveur sécurisé (protocole https://).

Inscription de l’application sur le serveur OAuthSD

L’application recevant le plugin doit être enregistrée en tant que client du serveur OAuthSD.
La procédure est décrite ici : OpenID Connect : Lier une application cliente au serveur OAuthSD.

En suivant cette procédure :
- vous vous inscrirez en tant qu’auteur sur le serveur OAuthSD,

- vous enregistrerez votre application. L’enregistrement se fait ici : Inscrire une application cliente.
Vous devrez :

  • configurer l’adresse de retour (Redirect URI) sous la forme suivante : https://mon_application.com/?action=auth
  • Inscrire au moins le scope "openid".

- l’installation et la configuration du plugin répond à l’étape 3 :

Installation et configuration du plugin

 Le plugin se trouve sur GitHub :
- https://github.com/bdegoy/oidcclient

Le plugin s’installe selon la procédure d’installation manuelle de tout plugin SPIP :

  • transférer le répertoire oidcclient dans le répertoire plugins,
  • activer le plugin dans l’administration.

- ouvrir le formulaire de configuration et indiquer l’ID de l’application cliente et son secret fournis lors de l’enregistrement de l’application sur le serveur OAuthSD :

Inscription en tant qu’utilisateur OpenID Connect

Pour enregistrer votre application, vous vous êtes inscrit sur ce serveur en tant qu’auteur. Pour utiliser le SSO OpenID Connect [2], vous devez vous inscrire en tant qu’utilisateur sur un serveur d’authentification compatible. Les deux inscriptions sont distinctes.

Si vous n’êtes pas déjà inscrit sur OAuthSD, vous devez vous s’inscrire sur ce serveur en tant qu’utilisateur.

Il faut ensuite établir une correspondance entre OpenID Connect et SPIP.

Correspondance entre l’utilisateur OpenID Connect et l’auteur (l’utilisateur) SPIP

Si vous tentez la connexion OpenID Connect avec un utilisateur inconnu de l’application, vous obtiendrez un message d’erreur comme celui-ci :

Il faut que l’utilisateur OpenID Connect soit lié à un compte d’auteur de l’application SPIP pour que celle-ci accepte la connexion. Ceci est réalisé en inscrivant le login OIDC dans le champ oidc de la fiche de l’auteur.

Bien entendu, pour faire cette modification, vous devrez fournir le mot de passe du compte d’auteur [3] :

Notes :
- On pourrait imaginer de créer un compte SPIP avec le même login, mais cela n’est pas nécessaire.
- On pourrait également penser à une autre solution : créer un nouvel utilisateur OpenID Connect avec le login SPIP ; Mais cela irait à l’encontre du principe de connexion unique (SSO) : si un utilisateur a une inscription sur OAuthSD, c’est pour pouvoir se connecter à différents systèmes avec les mêmes identifiants. La bonne solution est donc de lier un auteur SPIP à un compte OIDC pré-existant, non l’inverse.

Une fois liés les utilisateurs OpenID Connect et SPIP, le formulaire de connexion fait apparaître le lien et propose la connexion avec OIDC :

Dans cette situation, il reste possible de se connecter "normalement" en actionnant le lien "Ne pas utiliser OIDC, utiliser un mot de passe".

Notes :
- Un seul utilisateur OpenID Connect peut-être lié à un compte d’auteur de l’application SPIP. De même, un seul compte d’auteur de l’application SPIP peut être lié à un même utilisateur OpenID Connect.
- Seul les logins servent à établir la correspondance, les mots de passe sont propres à chaque système.

Connexion à l’application SPIP

Le plugin modifie le cadre de connexion de SPIP en ajoutant la possibilité d’utiliser OpenID Connect. La méthode classique reste disponible :

Entrez votre email ou votre signature (pseudo) puis :

Pour vous identifier avec OpenID Connect, assurez-vous que le champ "Mot de passe" est vide et actionnez le bouton "Valider".

Pour vous connecter avec la méthode standard, entrez le mot de passe d’auteur (ou utilisateur) SPIP avant d’appuyer sur le bouton "Valider".

Notes :
- Le plugin ajoute ’oidcclient’ à la liste des méthodes disponibles (variable $GLOBALS[’liste_des_authentifications’]). SPIP tente les différentes méthodes d’authentifications enregistrées en commençant par la méthode standard. En cas d’échec, SPIP passe à la méthode suivante.
- Si vous vous connectez avec la méthode standard, et que votre login ou mot de passe est faux, vous serez redirigé vers la connexion avec OpenID Connect. Dans cette situation, la fonctionnalité SLI pourrait aboutir à une connexion automatique.
- Si votre navigateur vous propose de mémoriser les identifiants de connexion, il est inutile de le faire : le mot de passe vu par le navigateur est crypté et change à chaque fois.

Monitoring

Le monitoring de l’état de l’authentification a pour but de synchroniser la connexion locale d’une application avec le jeton d’accès correspondant. Il permet notamment de visualiser l’état de connexion de l’utilisateur :

icône Signification
La connexion de l’utilisateur final n’est pas établie avec le serveur OIDC. Notez que l’utilisateur peut s’être connecté à l’application à l’aide de la méthode de connexion classique de SPIP.
L’utilisateur final et l’application sont connectés par OIDC.
Erreur générale, traduit malheureusement de multiples situations :
- perte de communication Internet,
- défaut de configuration du plugin,
- défaut d’inscription de l’application cliente sur le serveur OAuthSD,
- inscription de l’application sur un autre serveur, non compatible OAuthSD,
- login inconnu du serveur OAuthSD (l’utilisateur final n’est pas inscrit sur ce serveur),
- etc.
Le message peut éventuellement être plus explicite : "authentication error", ...
Notons que l’icône erreur peut apparaître brièvement au changement de page.

Le Monitoring permet également de manager la session OIDC et notamment d’effectuer la déconnexion globale (SLO).
En cliquant sur l’icône, des popups apparaissent selon l’état de connexion :

Une fonctionnalité du monitoring consiste à alerter l’utilisateur de la fin imminente de la session OIDC et lui permettre de la prolonger :

Notons que le monitoring a besoin pour fonctionner d’être appelé à partir d’un bloc div dans toutes les pages de votre application, par exemple dans le pied de page :

SPIP

[(#REM) Monitoring OAuthSD]
<div id="oidc_connexion">
   <INCLURE{fond=inclure/oidc_monitor, env} />
</div>

Pour plus d’information sur le monitoring voyez :
- Monitoring de l’état de l’authentification et SLO
- Avertir de la fin de session OIDC et la prolonger

Informations sur le serveur et la connexion OIDC

Un clic sur le point d’interrogation fait apparaître une fenêtre popup donnant les informations sur la connexion au serveur OIDC :

- Serveur : l’URL du serveur OIDC, cliquez pour atteindre le site support du serveur.
- Client ID : l’ID de l’application courante sur le serveur.
- Login SPIP : l’identifiant de connexion de l’utilisateur à l’application SPIP. Nul si l’utilisateur n’est pas connecté.
- Login OIDC : l’identifiant d’enregistrement de l’utilisateur sur le serveur OIDC (peut-être différent du précédent). Nul si l’utilisateur n’est pas connecté.
- T. session restant : la durée de vie restante de la session OIDC.
- Délai de réponse : durée de cycle de la dernière interrogation du contrôleur Authorize. Un temps anormalement long (supérieur à la seconde) peut traduire une connexion de données lente, une erreur de communication ou une surcharge du serveur OIDC. Si vous pensez que votre connexion de données est bonne, et si une durée anormalement longue persiste, contactez l’administrateur du serveur.

Commentaires et avertissements :

- Ce plugin n’est pas un remplacement ou un équivalent du plugin OpenID.

- Il reprend cependant le principe du plugin OpenID qui consiste à donner le choix entre la connexion avec OpenID Connect ou la méthode login/mot de passe classique. Merci aux auteurs d’OpenID à qui a été emprûntée la structure générale du plugin.

- OpenID Connect (OIDC) ne doit pas être confondu avec OpenID. La connexion automatique avec un identifiant OpenID universel n’existe pas dans le standard OIDC. OIDC offre une sécurité supérieure en permettant de construire un système propriétaire dans lequel les applications clientes et les serveurs, ainsi que les utilisateurs, sont limités à un ensemble bien identifié.

- Un utilisateur qui souhaite utiliser OIDC pour s’identifier doit être enregistré sur un serveur OIDC que lui a désigné le concepteur de l’application et dont l’URL est configurée dans l’administration de ce plugin.

- Un concepteur d’application qui utilise ce plugin doit enregistrer l’application en tant que client sur un serveur OpenID Connect.

Si vous voulez le faire sur ce serveur OAuthSD, il faut vous inscrire comme auteur et administrateur d’applications puis enregistrer l’application.

- Dans l’état actuel du développement, le plugin n’a été testé qu’en relation avec le serveur OauthSD (sur ce site web).

- Ce site web implémente un démonstrateur d’OAuthSD ; le serveur peut être indisponible et les données enregistrées effacées à tout moment.

- Aucune garantie d’aucune sorte n’est attachée à l’utilisation de ce serveur, des plugins, du code et de la documentation fourni par DnC.

- Le plugin est distribué sous licence GPL3.

- une partie sensible du source du plugin n’est pas fournie pour des raisons de sécurité.

FAQ

Erreur :
Le login OIDC xxx n’est pas lié à un compte de cette application.

Cette erreur apparaît après que vous avez validé le formulaire d’identification. Elle signifie que le login que vous avez indiqué dans ce formulaire n’est pas un login d’auteur de l’application SPIP à laquelle vous avez tenté de vous connecter. Reportez-vous au paragraphe "Correspondance entre l’utilisateur OpenID Connect et l’auteur (l’utilisateur) SPIP " ci-dessus.

Un conseil : faites simple, créez le login SPIP ou modifiez-le de façon à ce qu’il soit identique au login OIDC.
Ne créez pas un nouvel utilisateur OpenID Connect avec le login SPIP, cela est contraire au principe même de l’inscription unique (Single Sign On, SSO).

Question :
Quelle différence entre le lien "Se déconnecter" et "Clore la session OpenID Connect" ?

Cela dépend de la façon dont le lien "Se déconnecter" a été écrit par le développeur de l’application SPIP :
- si le lien contient le paramètre d’URL "logout=public", les deux méthodes sont équivalentes et conduiront à la déconnexion globale : toutes les applications actuellement connectées pour l’utilisateur authentifié seront déconnectées et la session OpenID Connect sera détruite ;
- si le lien contient le paramètre d’URL "logout=local", seule l’application courante sera déconnectée, la session OpenID Connect étant préservée.

Notes :
- Le plugin surcharge la fonction action_logout_dist(). Par défaut, toute utilisation de cette fonction, sans préciser le paramètre d’URL "logout=local" générera une demande de déconnexion vers OIDC.
- Il est peut-être préférable de na pas préciser "logout=local" afin de provoquer systématiquement la déconnexion globale, ce qui va dans le sens de la sécurité, particulièrement si une application est restée connectée sur un mobile ou une autre station de travail.

Question :
Et tout cela fonctionne avec un mobile ?
Oui, bien sûr, et pourquoi pas ?
En particulier, le mobile obéira bien à une déconnexion globale venant d’une autre application.

Question :
Est-ce que fermer le navigateur suffit à provoquer une déconnexion globale ?
Non.
Il faut explicitement clore la session OIDC.
D’ailleurs, si vous relancez le navigateur sur l’application que vous venez de quitter alors qu’elle était connectée, elle sera aussitôt reconnectée.
Il en est de même si on se contente de fermer l’onglet du navigateur dans lequel l’application était lancée et connectée.

Notes

[1Pour l’instant, ce plugin n’a été validé que sur le serveur OAuthSD (ce serveur).

[2Ne pas confondre avec OpenID

[3Y compris si l’opération est effectuée par l’administrateur, afin de protéger parfaitement les intérêts de l’utilisateur.

Service OAuthSD pour Lusitanian/PHPoAuthLib

  publié le par DnC

La bibliothèque Lusitanian/PHPoAuthLib fournit un support oAuth en PHP et est très facile à intégrer à tout projet nécessitant un client OAuth 2.

Cet article présente le code du service OAuthSD à inclure dans la librairie.


Si la classe Oauthsd n’est pas fournie par un plugin ou une extension, le code ci-dessous doit être inséré dans la librairie à l’emplacement et sous le nom indiqué :

.../vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Oauthsd.php

Notes :
- Le scope openid indique que nous utilisons la couche OpenID Connect.
- ’response_type’ => ’code’ indique que nous utilisons le flux Authorization code.
- Le scope "sli" permet (notamment) la connexion unique.
- Pour une utilisation en simple SSO, il est inutile de risquer de dévoiler les données de l’utilisateur avec le scope profile. En supprimant le scope profile, OAuthSD utilisera le scope par défaut basic, et seul le champ sub (subject) sera retourné par la demande d’authentification.

PHP

  1. <?php
  2. /**  
  3. * OpenID Connect Authentication with Oauthsd
  4. * @link     https://oa.dnc.global
  5. * Oauthsd.php OAuth service for the Lusitanian PHPoAuthLib
  6. * @link     https://github.com/Lusitanian/PHPoAuthLib
  7. * @author   Bertrand Degoy bertrand@degoy.com
  8. * @copyright (c) 2018 B.Degoy DnC https://degoy.com
  9. * @license  http://www.opensource.org/licenses/mit-license.html MIT License
  10. */
  11.  
  12. //dnc4
  13.  
  14. namespace OAuth\OAuth2\Service;
  15.  
  16. use OAuth\OAuth2\Token\StdOAuth2Token;
  17. use OAuth\Common\Http\Exception\TokenResponseException;
  18. use OAuth\Common\Http\Uri\Uri;
  19. use OAuth\Common\Consumer\CredentialsInterface;
  20. use OAuth\Common\Http\Client\ClientInterface;
  21. use OAuth\Common\Storage\TokenStorageInterface;
  22. use OAuth\Common\Http\Uri\UriInterface;
  23.  
  24.  
  25. class Oauthsd extends AbstractService
  26. {
  27.  
  28.     /**
  29.     * Available scopes (will be tested by AbstractService).
  30.     * Might be larger than those defined by client application.
  31.     * @link https://oa.dnc.global/-Sujets-communs-.html#definitionetgestiondesscopesdansOAuthsd
  32.     * @see  #attributes
  33.     */
  34.     const SCOPE_OPENID           = 'openid';
  35.     const SCOPE_PROFILE          = 'profile';
  36.     const SCOPE_EMAIL            = 'email';
  37.     const SCOPE_ADDRESS          = 'address';
  38.     const SCOPE_PHONE            = 'phone';
  39.     const SCOPE_SLI              = 'sli';
  40.  
  41.     public function __construct(
  42.         CredentialsInterface $credentials,
  43.         ClientInterface $httpClient,
  44.         TokenStorageInterface $storage,
  45.         $scopes = array(),
  46.         UriInterface $baseApiUri = null
  47.     ) {
  48.  
  49.         $scopes = array_merge($scopes, array(openid, sli, profile));   // profile ???
  50.  
  51.         parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
  52.  
  53.         if (null === $baseApiUri) {
  54.             $this->baseApiUri = new Uri('https://oa.dnc.global/');
  55.         }
  56.     }
  57.  
  58.     /**
  59.     * Override abstract function in order to provide required parameters in authorization request.
  60.     * State is required by OAuthSD
  61.     * Scopes :
  62.     * openid is required by OpenID Connect, sli is particular to OAuthSD, basic is enough for phpBB.
  63.     * @link https://oa.dnc.global/-Sujets-communs-.html#definitionetgestiondesscopesdansOAuthsd
  64.     */
  65.     public function getAuthorizationUri(array $additionalParameters = array())
  66.     {
  67.         $parameters = array_merge(
  68.             $additionalParameters,
  69.             array(
  70.                 //'type'          => 'web_server',
  71.                 'client_id'     => $this->credentials->getConsumerId(),
  72.                 'redirect_uri'  => $this->credentials->getCallbackUrl(),
  73.                 'response_type' => 'code',
  74.                 'scope'         => 'openid sli',    // do not mention basic.      
  75.             )
  76.         );
  77.  
  78.         if (!isset($parameters['state'])) {
  79.             $parameters['state'] = $this->generateAuthorizationState();
  80.         }
  81.         $this->storeAuthorizationState($parameters['state']);
  82.  
  83.         // Build the url
  84.         $url = clone $this->getAuthorizationEndpoint();
  85.         foreach ($parameters as $key => $val) {
  86.             $url->addToQuery($key, $val);
  87.         }
  88.         return $url;
  89.     }
  90.  
  91.     /**
  92.     * {@inheritdoc}
  93.     */
  94.     public function getAuthorizationEndpoint()
  95.     {
  96.         return new Uri('https://oa.dnc.global/authorize');
  97.     }
  98.  
  99.     /**
  100.     * {@inheritdoc}
  101.     */
  102.     public function getAccessTokenEndpoint()
  103.     {
  104.         return new Uri('https://oa.dnc.global/token');
  105.     }
  106.  
  107.     /**
  108.     * {@inheritdoc}
  109.     */
  110.     protected function getAuthorizationMethod()
  111.     {
  112.         return static::AUTHORIZATION_METHOD_HEADER_BEARER;        // ou AUTHORIZATION_METHOD_QUERY_STRING ???
  113.     }
  114.  
  115.     /**
  116.     * {@inheritdoc}
  117.     */
  118.     protected function parseAccessTokenResponse($responseBody)
  119.     {
  120.         $data = json_decode($responseBody, true);
  121.  
  122.         if (null === $data || !is_array($data)) {
  123.             throw new TokenResponseException('Unable to parse response.');
  124.         } elseif (isset($data['message'])) {
  125.             throw new TokenResponseException('Error in retrieving token: "' . $data['message'] . '"');
  126.         } elseif (isset($data['name'])) {
  127.             throw new TokenResponseException('Error in retrieving token: "' . $data['name'] . '"');
  128.         }
  129.  
  130.         $token = new StdOAuth2Token();
  131.         $token->setAccessToken($data['access_token']);
  132.         $token->setLifeTime($data['expires_in']);
  133.  
  134.         if (isset($data['refresh_token'])) {
  135.             $token->setRefreshToken($data['refresh_token']);
  136.             unset($data['refresh_token']);
  137.         }
  138.  
  139.         unset($data['access_token']);
  140.         unset($data['expires_in']);
  141.  
  142.         $token->setExtraParams($data);
  143.  
  144.         return $token;
  145.     }
  146.  
  147.     /**
  148.     * {@inheritdoc}
  149.     */
  150.     public function requestAccessToken($code, $state = null)
  151.     {
  152.         if (null !== $state) {
  153.             $this->validateAuthorizationState($state);
  154.         }
  155.  
  156.         $bodyParams = array(
  157.             'code'          => $code,
  158.             'client_id'     => $this->credentials->getConsumerId(),
  159.             'client_secret' => $this->credentials->getConsumerSecret(),
  160.             'redirect_uri'  => $this->credentials->getCallbackUrl(),
  161.             'grant_type'    => 'authorization_code',
  162.         );
  163.  
  164.         $responseBody = $this->httpClient->retrieveResponse(
  165.             $this->getAccessTokenEndpoint(),
  166.             $bodyParams,
  167.             $this->getExtraOAuthHeaders()
  168.         );
  169.        
  170.         $token = $this->parseAccessTokenResponse($responseBody);
  171.         $this->storage->storeAccessToken($this->service(), $token);
  172.  
  173.         return $token;
  174.     }
  175. }

Télécharger

Feuille de route

Dans une organisation fermée (corporate realm), on souhaite posséder son propre serveur OIDC et obtenir des données Userinfo selon un format spécifique, généralement en utilisant une base user existante.
Pour cela, il faudrait :
- une fonction setter pour l’URL du serveur OIDC afin de pouvoir choisir le serveur d’authentification.
- une fonction setter pour configurer les données de Userinfo.
- cela devrait conduire à un client OpenID Connect universel. Tenter alors un pull request vers lusitanian ?