Accueil > OpenID Connect OAuth Server par DnC > Développer > OpenID Connect

OpenID Connect est un protocole d’authentification construit au-dessus de OAuth qui en constitue la couche de délégation d’autorisations.

Généralités sur l’authentification, introduction d’OpenID Connect Ou la nécessité de compléter OAuth

  publié le par DnC

OpenID Connect est une couche d’identité au dessus de l’architecture de délégation d’autorisation OAuth 2.0 permettant aux applications :
- de vérifier l’identité de l’usager et de la lier à une application et à une portée d’autorisation,
- d’obtenir des informations de base (attributs) concernant le profil de l’usager.

On croit souvent que l’usage d’OpenID Connect impose d’utiliser un compte Google, Facebook ou Twitter etc. OAuth Server by DnC implémente OpenID Connect sur un serveur privé, le vôtre éventuellement, et offre donc la confidentialité d’une alternative indépendante.

OAuth est-il un système d’authentification ?

L’authentification suppose que l’application protégée, qui reçoit une autorisation de délivrer les informations à l’application cliente, puisse identifier l’utilisateur final qui est à l’origine de l’autorisation.
OAuth ne fournit pas cette identité et doit être complété pour assurer l’authentification.

OpenID Connect

OpenID Connect est une couche d’authentification construite sur OAuth 2.0. Le serveur d’autorisation (ou "fournisseur OpenID" dans ce cas, en anglais OpenID Provider ou OP) contient des informations sur une personne. OAuth est utilisé pour protéger ces informations, permettant à une application tierce (client) d’y accéder au nom de cette personne. Pour autoriser la diffusion d’informations, la personne est authentifiée et le Fournisseur OpenID fournit au client des détails notamment sur l’identité de la personne et le moment de l’authentification.

En plus du jeton d’accès, OpenID Connect met en oeuvre le jeton JWT (JSON Web Token) qui contient des informations sur l’utilisateur authentifié. Le jeton d’identification est signé par le serveur d’autorisation et peut être lu et vérifié sans accéder au serveur d’autorisation. C’est cette caractéristique qui doit conduire à choisir OpenID Connect, en réponse à la problématique de la Validation du jeton d’accès par une ressource protégée.

En outre, OpenID Connect standardise différentes choses que OAuth laisse au choix du développeur. Par exemple les scopes, la découverte des points d’extrémité et l’enregistrement dynamique des clients.

OpenID Connect : Types d’autorisations (Grant Type)

  (publié initialement le jeudi 22 décembre 2016) par DnC

Les flux d’autorisation (Grant Type) spécifiquement définis pour le protocole OpenID Connect sont :
- Autorisation via un code (Authorization Code Grant),
- Autorisation implicite (Implicit Grant),
- Flux Hybride (Hybrid Flow).


Voyez également : OpenID Connect : Synthèse des flux d’autorisation (Grant Type).


Flux de code d’autorisation (spéc. : Authorisation code flow) - le flux le plus couramment utilisé, destiné aux applications Web traditionnelles ainsi qu’aux applications natives / mobiles. Implique une redirection initiale du navigateur vers le serveur d’authentification pour l’authentification et le consentement de l’utilisateur, puis une seconde demande de l’application cliente pour récupérer le jeton d’ID.

Le diagramme de ce flux est identique à son homologue d’OAuth 2.0, la différence étant le jeton d’identification (ID Token) qui accompagne le jeton d’accès.

La signature de ce jeton offre aux serveurs de ressource protégée (RS) l’opportunité de valider le jeton localement, pourvu qu’une forme de clé leur soit connue.

Le flux de code d’autorisation offre une sécurité optimale, car :
- le secret de l’application, résidant sur le serveur, est protégé,
- les jetons ne sont pas révélés au navigateur (ne circulent que dans une liaison serveur-serveur),
- l’application cliente peut être authentifiée, tout comme l’utilisateur final,
- la signature du jeton lie de façon indissoluble : l’identité de l’utilisateur final, l’identité de l’application, la portée (scope) de l’autorisation.

La mise en œuvre de ce flux dans le cadre d’OAuthSD est détaillée ici : OpenID Connect : Autorisation via un code (Authorization Code Flow).

Flux implicite (spéc. : Implicit flow) - pour les applications basées sur un navigateur qui n’ont pas de backend, par exemple une application Javascript. Ce flux est également utilisé pour les applications à page unique (SinglePage Application, SPA). Le jeton d’identification est reçu directement avec la réponse de redirection de l’OP. Aucun appel au canal de retour n’est requis ici. De ce fait, le client ne peut être authentifié.

La mise en œuvre de ce flux dans le cadre d’OAuthSD est détaillée ici : Autorisation implicite.

Flux Hybride (spéc. : Hybrid Flow) - Essentiellement une combinaison du code et des flux implicites, rarement utilisé. On peut lire : "Permet à l’application front-end et back-end de recevoir des jetons séparément l’une de l’autre". Il semble plus sécurisé et tout aussi facile d’appliquer séparément un flux de code et un flux implicite.

Les flux Implicite et Hybride sont implémentés par OAuthSD mais leur usage est découragé car ils ne présentent pas les avantages de sécurité attachés à OpenID Connect :
- ils compromettent le secret de l’application qui est facilement accessible au public,
- ils exposent les jetons au navigateur de l’utilisateur final, ce qui rend possible une exploitation par un malware,
- ils ne permettent pas d’authentifier l’application cliente.

Notes :
- Les fonctionnalités d’OAuth 2.0 sont intégrées au protocole OpenID Connect. Toutes les fonctionnalités d’OAuth 2.0 et de OpenID Connect peuvent donc être atteintes par les Points d’extrémité d’OpenID Connect, en particulier les flux Client/User Credentials d’OAuth 2.0. Tous les flux sont résumés ici : OpenID Connect : Synthèse des flux d’autorisation (Grant Type).
- Le flux Hybrid n’est que partiellement implémentée par OAuthSD. Cette méthode est peu utilisée et peut être avantageusement remplacée par une successsion d’appels aux deux premières.

OpenID Connect : Lier une application cliente au serveur OAuthSD

  publié le par DnC

Cet article s’adresse à un développeur.

Il décrit comment adapter une application pour qu’elle devienne cliente OpenID Connect et comment l’inscrire sur OAuth Server byDnC.

Ceci suppose que le développeur ou son organisation soit inscrit sur le serveur en tant qu’Administrateur d’applications.

Le processus comporte deux aspects :

- du côté du serveur OAuth, inscrire l’application,
- du côté de l’application cliente, insérer le code nécessaire pour assurer le lien avec le serveur OAuth.

1. S’inscrire en tant qu’Administrateur d’applications

L’inscription se fait ici : Formulaire d’inscription.

Renseignez soigneusement votre fiche d’Administrateur d’applications, la plupart de ces informations étant communiquées aux utilisateurs finaux dont vous devez gagner la confiance.

Attention : ne confondez pas l’inscription en tant qu’Administrateur d’applications (un développeur qui inscrit son application cliente pour qu’elle puisse déléguer l’authentification à OAuthSD) avec l’inscription d’un internaute en tant qu’utilisateur final des applications clientes, qui se fait ici : Je m’inscris.

Notes :
- Le terme "Administrateur d’applications" permet de distinguer le développeur ou le propriétaire d’une application cliente qui s’inscrit sur ce serveur, de l’utilisateur final, qui doit aussi s’inscrire, mais autrement. Dans le modèle de données sous-jacent, il s’agit également de l’objet éditorial de SPIP (la table auteurs), tandis que l’utilisateur final correspond à une table distincte.

2. Inscrire l’application cliente sur le serveur OAuthSD

Dans la rubrique Gérer, aller à Ajouter (Inscrire) une application cliente et remplir le formulaire :

- Client Id (obligatoire) : Chaine identifiant l’application de façon unique. Entrez un nom court, sans espace ni caractère spécial autre que ’_’. Cet identifiant doit être unique pour tous les administrateurs d’applications inscrits sur le serveur. Il est visible du public et doit donc être représentatif de l’application et de votre entreprise.

- Client secret (obligatoire) : une courte chaîne assimilable à un mot de passe fort. Ce code doit rester secret. Il doit être fourni par l’application cliente lors de la demande de jeton.

- Redirect uri (obligatoire) : URI de retour à l’application cliente. C’est l’adresse à laquelle le serveur OAuth fait retour sur le client avec le résultat de l’authentification. OpenID Connect permet d’inscrire plusieurs URI de retour, cependant cette fonctionnalité n’a pas été testée dans l’état actuel du développement.

- Grant Type (obligatoire) : Sauf cas particulier, sélectionnez au moins "Authorization Code". Pour les flux Hybrid, sélectionnez "Authorization Code" et "Implicit". Voyez OpenID Connect : Synthèse des flux d’autorisation (Grant Type).

- Scopes (obligatoire) : Liste des Scopes autorisés pour l’application, séparés par un espace. Le scope ’openid’ est obligatoire. Les scopes standard de OpenID Connect sont : profile, email, address, phone. Voyez la rubrique : Réponse UserInfo. Le scope ’offline_access’ sert à obtenir un jeton de rafraîchissement. En plus de ces scopes, des scopes particuliers peuvent être définis pour une application donnée. Exemple : "openid profile email administrateur".

- User id Si un nom d’utilisateur (username) est inscrit ici, seul cet utilisateur pourra se connecter, cet identifiant étant figé dans le formulaire d’authentification. Dans le cas général ce champ sera vide.

Vérifiez vos entrées et actionnez le bouton "Enregistrer".

Enfin, naviguez à l’adresse https://oa.dnc.global/keys afin de créer l’entrée correspondant à la nouvelle paire de clés publique/privée.

Vous pourrez retrouver l’application et la modifier à la rubrique Toutes vos applications clientes.

Notes :
- OAuthSD crée pour l’application cliente une paire de clés publique/privée. Si vous souhaitez la changer, allez à la rubrique Toutes vos applications clientes et sélectionnez l’action "clés" correspondant à l’application.

3. Insérer dans l’application le code nécessaire

Bien que OpenID Connect soit construit sur OAuth 2.0, il ne faut pas s’attendre à réutiliser le code écrit pour ce protocole. En effet, OpenID Connect est une couche d’abstraction de niveau supérieur, impliquant des échanges et des points d’extrémité différents, ce qui nécessite que le code soit réécrit.

Si l’application cliente est conçue pour déléguer ses authentifications à un serveur à la norme OpenID Connect, il n’y a rien de plus à faire. En effet, OAuthSD est 100% compatible OIDC ; les fonctionnalités supplémentaires sont apportées de façon transparente.

Si l’applicatif sur lequel est construit l’application cliente propose un plugin OpenID Connect, il suffira de l’installer. Nous proposons quelques plugins ici : Ressources pour les développeurs.

Sinon, c’est une affaire de développeur. Il y a deux adaptations à réaliser :

- Écrire le code situé au Point d’extrémité de redirection, ou URI de retour à l’application cliente (Redirection Endpoint). Il s’agit de demander au serveur OAuthSD un jeton d’accès et un jeton d’identification pour l’application, à partir du Code d’autorisation (Authorization code) retourné par le serveur.

- Écrire la procédure d’authentification adaptée à la technique de l’application cliente. Généralement, ce sera un module d’authentification supplémentaire, ou une ré-écriture du code d’authentification. Voyez : Plugin OpenID Connect Client pour SPIP, Extension OpenID Connect pour phpBB, Extension pour Wordpress "OpenID Connect Generic Client".

De façon optionnelle, on pourra également :
- Afficher l’état de la session OIDC et la gérer (Monitoring).

Consommer une API protégée de type HTTP REST : Un cas simple

Consommer une API protégée de type HTTP REST est extrêmement simple. Voici un exemple élémentaire, juste pour tester le fonctionnement, combinant en un seul script l’autorisation et la consommation de UserInfo :

PHP

  1. <?php
  2. /*
  3. testopenid2.php
  4.  
  5. Test de OpenID Connect
  6. Inscrivez sur ce serveur une application de test,
  7. Renseignez les constantes ci-dessous en conséquence,
  8. Lancez ce script : http://oa.dnc.global/oidc/testopenid2.php
  9.  
  10. Author :
  11. Bertrand Degoy https://degoy.com
  12. Credits :
  13. bschaffer https://github.com/bshaffer/oauth2-server-php
  14.  
  15. Licence : GPL v3.0
  16. Copyright (c) 2016 - DnC
  17.  
  18.  
  19. */
  20.  
  21. ini_set('display_errors', 1);
  22.  
  23. $client_id = 'testopenid';
  24. $client_secret = 'thesecret';
  25. //$redirect_uri = '';
  26.  
  27. $authorization_endpoint = 'https://oa.dnc.global/authorize';
  28. $token_endpoint = 'https://oa.dnc.global/token';
  29. $userinfo_endpoint = 'https://oa.dnc.global/userinfo';
  30.  
  31.  
  32. if (isset($_GET['error']))
  33. {
  34.     exit("Error: {$_GET['error']}. Description: {$_GET['error_description']}");
  35. }
  36. else if (isset($_GET['code']) && isset($_GET['state']))
  37. {
  38.     // Step 2. Token request
  39.  
  40.     $code = $_GET['code'];
  41.     echo "Authorization Code is {$code}\n\n";
  42.  
  43.     $data = array(
  44.         'grant_type' => 'authorization_code',
  45.         'code' => $code,
  46.     );
  47.  
  48.     $h = curl_init($token_endpoint);
  49.     curl_setopt($h, CURLOPT_RETURNTRANSFER, true);
  50.     curl_setopt($h, CURLOPT_TIMEOUT, 10);
  51.     curl_setopt($h, CURLOPT_USERPWD, "{$client_id}:{$client_secret}");
  52.     curl_setopt($h, CURLOPT_POST, true);
  53.     curl_setopt($h, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
  54.     curl_setopt($h, CURLOPT_POSTFIELDS, http_build_query($data));
  55.     //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
  56.  
  57.     $res = curl_exec($h);
  58.     if (!$res)
  59.         exit(curl_error($h));
  60.  
  61.     curl_close($h);
  62.     $res = json_decode($res, true);
  63.  
  64.     echo "Token Response:\n";
  65.     print_r($res);
  66.     echo "\n";
  67.  
  68.     // Here you should decode JWT token and check signature using server's public key
  69.     // $payload = Jwt::decode($response['id_token'], $this->serverPublicKey);
  70.  
  71.     // If Token Response is valid goto step 3
  72.     // Step 3. Get UserInfo
  73.     $access_token = $res['access_token'];
  74.  
  75.     $h = curl_init($userinfo_endpoint);
  76.     curl_setopt($h, CURLOPT_RETURNTRANSFER, true);
  77.     curl_setopt($h, CURLOPT_TIMEOUT, 10);
  78.     curl_setopt($h, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $access_token));
  79.     //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
  80.  
  81.     $res = curl_exec($h);
  82.     if (!$res)
  83.         exit(curl_error($h));
  84.  
  85.     curl_close($h);
  86.     $res = json_decode($res, true);
  87.  
  88.     echo "UserInfo Response:\n";
  89.     print_r($res);
  90. }
  91. else
  92. {
  93.     // Step 1. Authorization Code request
  94.  
  95.     $data = array(
  96.         'response_type' => 'code',
  97.         'client_id' => $client_id,
  98.         'state' => 'xyz',
  99.         'scope' => 'openid profile',    
  100.     );
  101.  
  102.     $authorization_endpoint .= '?' . http_build_query($data);
  103.     header('Location: ' . $authorization_endpoint);
  104.     exit();
  105. }
  106. ?>

Télécharger

Exécuter le script : https://oa.dnc.global/oidc/tests/te...

Sur le serveur OAuthSD, vous pouvez vous identifier avec login = bebert et password = 012345678

Une version rigoureuse et donc plus complète est donnée ici : OpenID Connect : Exemples complets du flux d’Autorisation via un code puis requête UserInfo.