API, authentification

Arriver à se parler, c'est bien, il reste à répondre à une question existentielle : comment le serveur sait-il que le client est bien celui qu'il prétend être ? Par Brian Cooksey

Par

Les choses commencent à prendre forme et nous comprenons mieux les API. Nous savons qui sont le client et le serveur, nous savons qu'ils se parlent grâce à HTTP, et nous savons qu'ils utilisent des formats spécifiques de données pour se comprendre. Savoir parler, c'est bien, mais il reste encore une question : comment le serveur sait-il que le client est bien celui qu'il prétend être ?

Les identités dans un monde virtuel

Vous vous êtes certainement déjà enregistré sur un compte web, le processus commence avec quelques questions personnelles, nom d'utilisateur, mot de passe, qui deviennent vos identifiants. Lorsque vous retournez sur le site, vous pouvez vous identifier grâce à ces identifiants (credentials).

Il s'agit là d'un des procédés techniques connus sous le nom d'authentification. Quand vous vous authentifiez auprès d'un serveur, vous prouvez votre identité en lui donnant des informations que vous êtes (en principe) seul à connaître. Une fois que le serveur sait qui vous êtes, il peut vous faire confiance et vous donner accès aux données privées de votre compte.

Les API utilisent plusieurs techniques pour authentifier un client, on les appelle des systèmes d'authentification. Penchons-nous sur trois d'entre eux.

Authentification basique

L'exemple de login que nous venons de voir est la forme la plus simple d'authentification, on l'appelle officiellement Authentification Basique (“Basic Auth” pour les amis). Celle-ci ne demande qu'un nom d'utilisateur et un mot de passe. Le client prend ces deux identifiants et les transforme en une valeur unique, qu'il passe dans la requête grâce à un header HTTP appelé Authorization.

l'authorization dans le header

Figure 1 - Le header HTTP Authorization

À réception de la requête, le serveur compare le header Authorization et les identifiants qu'il a enregistrés. Si le nom d'utilisateur et le mot de passe correspondent à ceux d'un utilisateur dans la liste, le serveur accomplit la requête de l'utilisateur. Sinon, il retourne un code de statut spécial (401) pour faire savoir au client que l'authentification a échoué et la requête est rejetée.

Bien que nous soyons en présence d'un système valide, le fait que l'authentification basique utilise les mêmes noms d'utilisateur et mot de passe à la fois pour accéder à l'API et pour gérer le compte n'est pas idéal. C'est un peu comme si un hôtel vous donnait les clés de tout le bâtiment plutôt que les clés de votre chambre.

Il en va de même avec les API, le client devrait parfois avoir des permissions différentes de celles du propriétaire du compte. Prenez l'exemple d'une entreprise qui engage un fournisseur pour écrire une API pour son compte. Faire confiance au fournisseur en lui donnant ses identifiants crée un risque, face à un fournisseur sans scrupule qui changerait le mot de passe, l'entreprise n'ayant plus accès à son propre compte. Il serait donc souhaitable d'avoir une solution alternative.


images de clés


Authentification par une clé API

Cette technique résoud le problème des identifiants partagés, l'accès à l'API se faisant au moyen d'une clé unique. Dans ce système, la clé est généralement une longue série de lettres et de chiffres distincte du mot de passe du propriétaire du compte. Celui-ci donne la clé au client, tout comme un hôtel donne la clé de sa chambre à un hôte.

Lorsque le client s'authentifie au moyen de la clé API, le serveur sait qu'il peut lui donner accès aux données, mais maintenant il a aussi l'option de limiter l'accès à certaines fonctions administratives, comme changer les mots de passe ou effacer des comptes. Dans certains cas, le rôle de la clé est simplement d'éviter que l'utilisateur n'ait à donner son mot de passe : les clés d'authentification API peuvent donc servir à limiter le contrôle ou à protéger les mots de passe de l'utilisateur.

Alors où indiquons-nous la clé API ? Il y a un header pour ça, pas vrai ? Eh bien non. Contrairement à l'authentification basique, qui est un standard bien établi avec des règles strictes, les clés API ont été conçues par des entreprises diverses dans les jours anciens du web, et le résultat est qu'on est ici dans l'Ouest sauvage : chacun fait à sa façon.

Avec le temps cependant, certaines approches communes ont émergé. L'une d'entre elles consiste à mettre la clé dans le header Authorization, à la place du nom d'utilisateur et du mot de passe. Une autre consiste à ajouter la clé à l'URL (http://example.com?api_key=my_secret_key). Il arrive, moins communément, qu'on enterre la clé quelque part dans le body de la requête, au milieu des données. Où qu'elle se trouve, son effet est le même - elle permet au serveur d'authentifier le client.

Nous allons voir maintenant une troisième solution, l'Autorisation Ouverte (Open Authorization, connue comme OAuth), qui est en train de devenir le système d'authentification le plus courant sur le web.

Simplifier la vie

Avez-vous déjà eu à remplir un formulaire comme celui-ci ?

Figure 2 - Une clé produit, sur une formulaire d'enregistrement de Microsoft

Taper une longue clé dans un champ de formulaire constitue une bien pauvre expérience utilisateur. D'abord vous devez trouver la clé. Oui, elle était dans votre boîte de réception quand vous avez acheté le logiciel, mais un an après c'est la galère pour la retrouver (quel était l'expéditeur de l'email ? quelle adresse mail ai-je utilisé pour m'enregistrer ?). Une fois retrouvée, vous devez entrer cette fichue clé parfaitement - une erreur, un oubli et tout est à refaire, encore heureux si vous ne vous retrouvez pas enfermé dehors sans pouvoir vous réenregistrer !

Forcer les utilisateurs à travailler avec des clés API n'est pas non plus une bonne expérience. Les fautes de frappe sont une erreur commune et une partie du travail doit être faite manuellement. L'utilisateur doit obtenir la clé du serveur, puis la donner au client. Pour des outils supposés automatiser le travail, il doit y avoir une meilleure solution.

C'est ici qu'entre en scène OAuth. Un des principaux problèmes résolus par OAuth est l'automatisation de l'échange de clés. Il fournit au client une manière standard d'obtenir une clé du serveur en passant par quelques étapes simples. Du point de vue de l'utilisateur, tout ce que demande OAuth est d'entrer ses identifiants. En arrière-plan, le client et le serveur discutent ferme afin d'obtenir une clé pour le client.

Il existe actuellement deux versions d'OAuth, nommées... OAuth 1 et OAuth 2. Pour interagir avec les API qui les utilisent, il faut bien comprendre chaque étape du processus. Celui-ci étant commun aux deux, nous allons nous intéresser d'abord à OAuth 2 puis relever les différences avec OAuth 1.

OAuth 2

Pour commencer, faisons connaissance avec les acteurs impliqués dans un échange OAuth :

L'utilisateur - une personne qui souhaite connecter deux sites web
Le client - Le site web à qui l'on accorde l'accès aux données de l'utilisateur
Le serveur - Le site web qui possède les données de l'utilisateur

Ensuite, un avertissement rapide. L'un des buts de OAuth est de permettre aux entreprises d'adapter le processus d'authentification à leurs besoins. En raison de cette nature extensible, les API peuvent comporter des étapes différentes. Le déroulement des opérations que nous montrons ci-dessous est un exemple courant parmi les applications web. Les applications mobile et desktop peuvent présenter de légères variations.

Ceci étant posé, voici les étapes d'OAuth 2.

Étape 1 - L'utilisateur demande au client de se connecter au serveur

L'utilisateur déclenche le processus en faisant savoir au client qu'il veut se connecter au serveur - en général en cliquant sur un bouton.

Étape 2 - Le client dirige l'utilisateur vers le serveur

Le client envoie l'utilisateur sur le site du serveur, en même temps qu'une URL à laquelle le serveur retournera l'utilisateur lorsqu'il se sera authentifié, et qu'on appelle Callback URL.

Étape 3 - L'utilisateur se connecte au serveur et donne accès au client

L'utilisateur s'authentifie auprès du serveur avec son nom d'utilisateur et son mot de passe. Le serveur est maintenant certain que l'un de ses utilisateurs demande que le client puisse avoir accès au compte de l'utilisateur et à ses données.

Étape 4 - Le serveur renvoie l'utilisateur au client, avec un code

Le serveur renvoie l'utilisateur au client (vers l'URL de callback de l'étape 2). Caché dans la réponse se trouve un code unique d'autorisation pour le client.

Étape 5 - Le client échange le code et la clé secrète contre un jeton d'accès
Le client prend le code d'autorisation qu'il a reçu et envoie une autre requête au serveur. Cette requête comprend la clé secrète du client. Lorsque le serveur voit un code d'autorisation valide et la clé secrète d'un client de confiance, il est certain que le client est bien celui qu'il prétend être, et qu'il agit au nom d'un utilisateur réel. Le serveur répond en envoyant un jeton d'accès (access token).

Étape 6 - Le client va chercher les données dans le serveur

À ce moment, le client est libre d'accéder au serveur au nom de l'utilisateur. Le jeton d'accès de l'étape 5 est au fond un autre mot de passe à l'intérieur du compte de l'utilisateur sur le serveur. Le client intègre le jeton d'accès à chaque requête afin de s'authentifier automatiquement auprès du serveur.

Le client rafraîchit le jeton (optionel)
Avec OAuth 2 a été introduite une option d'expiration des jetons d'accès, afin de protéger les comptes d'utilisateurs en renforçant la sécurité - plus vite la validité d'un jeton expire, moins un jeton volé a de chances d'être utilisé à des fins malveillantes, tout comme une carte de crédit a une date de validité. La durée de vie du jeton est déterminée par le serveur, elle peut aller de quelques heures à quelques mois. Une fois la durée atteinte, le client doit demander un nouveau jeton au serveur.

OAuth 1, les différences

Il y a plusieurs différences importantes entre les deux versions d'OAuth. L'une d'elles a déjà été mentionnée : les jetons d'accès n'ont pas de durée de validité.

Une autre distinction est que OAuth 1 inclut une étape supplémetaire. Entre les étapes 1 et 2 ci-dessus, OAuth 1 exige que le client demande au serveur un jeton de requête (request token). Ce jeton se comporte comme le code d'autorisation dans OAuth 2 et c'est en son échange que sera donné le jeton d'accès.

Une troisième différence est que OAuth 1 exige que les requêtes soient signées numériquement. Nous passerons sur les détails du fonctionnement de cette signature, mais il est intéressant de savoir pourquoi elle existe dans une version et pas dans l'autre. Signer une requête contribue à protéger les données contre des altérations possibles lors du transfert entre client et serveur. La signature permet au serveur de vérifier l'authenticité de la requête.

Aujourd'hui cependant, le trafic des API passe par un canal qui est déjà sûr (HTTPS), c'est pourquoi OAuth 2 a éliminé les signatures afin de rendre la version 2 plus facile d'utilisation.

Autorisation

Il y a un élément de OAuth 2 qui mérite une attention particulière, c'est le concept de limitation d'accès, appelé autorisation. Si nous revenons à l'étape 2, lorsque l'utilisateur clique sur le bouton pour permettre l'accès du client, bien cachées quelque part se trouvent les permissions exactes que le client demande. Ces permissions, appelées scope, sont une caractéristique importante de OAuth 2. Elle donnent au client une façon de requérir un accès limité aux données de l'utilisateur.

Ce qui fait la puissance de scope, ce sont les restrictions client. Contrairement à une clé API, où les limites intégrées dans la clé affectent chaque client sans distinction, le scope OAuth permet d'accorder à un client une permission X et à un autre les permissions X et Y. En conséquence, un site web pourrait être capable de voir vos contacts alors qu'un autre pourrait les voir et les modifier.

Récapitulation

Dans cet article nous avons appris comment le client peut prouver son identité au serveur, un processus appelé authentification et nous avons vu deux techniques utilisées par les API à cet effet. Nous avons étudié le processus d'authentification OAuth et comparé les deux versions en relevant leurs principales différences.

Les termes-clés que nous avons appris sont :

Authentification : processus par lequel un client prouve son identité au serveur
Identifiants (credentials) : informations secrètes utilisées pour prouver l'identité du client (nom d'utilisateur, mot de passe…)
Autorisation basique : technique utilisant un nom d'utilisateur et un mot de passe codés en tant qu'identifiants
Clé API : technique utilisant une clé unique en tant qu'identifiant
header authorization : le header HTTP dans lequel figurent les identifiants
OAuth : un système d'authentification qui automatise l'échange de clés entre le client et le serveur
Jeton d'accès : un code secret que le client obtient au terme du processus OAuth
Scope : des permissions qui déterminent le type d'accès accordé au client

Dans le prochain article, nous verrons les principes de base de la conception d'une API, y compris la façon d'organiser les données pour permettre aux clients de trouver facilement ce qu'ils cherchent.

Lire l'article suivant.


Liste des articles parus :


original paru le dans Zapier.com.

Sur l'auteur : travaille chez Zapier.com, vous pouvez le suivre sur Twitter ainsi que Zapier.

Traduit avec l'aimable permission de Zapier et de l'auteur.
Copyright Zapier © 2014.