Précédent Attaques par en-tête d'hôte HTTP
Suivant Une philosophie de la conception de logiciels

OAuth et OpenID Connect

OpenID a été la première norme visant à déléguer le processus de connexion à un autre site sans avoir à ressaisir sans cesse les informations de connexion.

Depuis, le choix de l'industrie concernant les mécanismes de délégation d'authentification et d'autorisation semble se diriger de plus en plus vers OAuth et OpenID Connect.

Voici quelques notes sur ces protocoles et sur la différence entre identification/authentification et autorisation.

Identification/authentification et autorisation

L'identification consiste à établir l'identité d'un utilisateur : "Qui êtes-vous ?". On peut faire une analogie avec l'identifiant (username ou login etc.).

L'authentification consiste à apporter une preuve de l'identité d'un utilisateur : "Êtes-vous réellement cette personne ?". C'est par exemple le mot de passe.

En pratique identification et authentification vont de pair.

L'autorisation consiste à déterminer des droits d'accès à des données : "Qu'avez-vous le droit de faire sur ce système ?".

OAuth 1.0a (Open Authorization)

OAuth permet aux utilisateurs de donner à un site ou logiciel "consommateur" (Consumer), l'accès à des informations personnelles provenant d'un site "fournisseur de service ou de données" (Service Provider), sans avoir à transmettre l'identifiant et le mot de passe des utilisateurs.

Le protocole OAuth (RFC 5849) date de 2007 et est construit autour d'un concept central : la délégation d'autorisation.

Le protocole OAuth fonctionne avec HTTP et comprend deux parties principales : l'obtention d'un jeton en demandant à l'utilisateur son consentement, et l'utilisation du jeton pour accéder à des ressources protégées.

Les méthodes d'obtention du jeton sont appelées flows.

OAuth 1 dispose d'un flow principal appelé OAuth authorization flow composé de huit étapes :

Ce flow alambiqué connu sous le nom de three-legged OAuth nécessite l'utilisation d'un navigateur web pour obtenir le consentement d'un utilisateur et découle de la volonté d'empêcher le Consumer de manipuler les données d'identification de l'utilisateur (identifiant et mot de passe). En impliquant trois parties, seul un minimum d'informations est fourni afin de permettre l'accès aux ressources d'un utilisateur. Un mot de passe potentiellement faible est remplacé par un jeton opaque pouvant être révoqué par l'application ou l'utilisateur.

Un flow alternatif et officieux nommé two-legged OAuth permet d'impliquer uniquement deux parties dans le processus. Le Consumer agit en son nom propre, sans intervention de l'utilisateur, et devient propriétaire des ressources. Il doit s'enregistrer auprès du Service Provider pour obtenir les Consumer Key et Consumer Secret.

Une spécificité d'OAuth 1 réside dans le fait que les Access Tokens n'expirent généralement pas et peuvent être réutilisés jusqu'à leur révocation par l'utilisateur. En détenant les Access Tokens du propriétaire d'une ressource (obtenus après un premier consentement) et ceux du Consumer, il est possible via un client OAuth1 de zapper la redirection qui demande son consentement à l'utilisateur, voir l'exemple 4 de Requests-OAuthlib :

>>> protected_url = "https://api.twitter.com/1/account/settings.json"

>>> oauth = OAuth1(
    CLIENT_KEY,
    client_secret=CLIENT_SECRET,
    resource_owner_key=RESOURCE_OWNER_KEY,
    resource_owner_secret=RESOURCE_OWNER_SECRET,
)
>>> r = requests.get(url=protected_url, auth=oauth)

La sécurité d'OAuth 1 repose sur la signature de la demande du consommateur à l'aide de HMAC-SHA1, RSA-SHA1 ou PLAINTEXT. Des nonces et des timestamps sont utilisés en tant que mécanismes de sécurité supplémentaires.

OAuth 2.0 (Open Authorization)

Au fil du temps, le flow unique d'OAuth 1 a montré ses limites. De plus, le fait de devoir signer les requêtes et la complexité du mécanisme d'obtention du jeton d'accès figurent parmi les principales critiques formulées à l'égard du protocole.

C'est sur ce terreau que le protocole OAuth 2.0 arrive en 2010, sans rétrocompatibilité.

OAuth 2.0 propose plusieurs flows et délègue la sécurité au protocole HTTPS. Au rang des autres nouveautés, les Access Tokens peuvent être de courte durée (short-lived) avec une possibilité de rafraîchissement.

OAuth 2.0 est une spécification née dans la douleur, vous pouvez lire OAuth 2.0 and the Road to Hell et un contre-avis dans On the Deadness of OAuth 2.

Le flow classique d'autorisation OAuth (OAuth authorization flow ou OAuth dance) a été simplifié :

  1. Consumer : envoi de l'utilisateur vers le Service Provider
  2. Service Provider : demande du consentement de l'utilisateur
  3. Service Provider : redirection de l'utilisateur vers le Consumer avec un Authorization Code qui représente le consentement de l'utilisateur
  4. Consumer : utilisation de l'Authorization Code pour l'échanger contre un Access Token qui représente une autorisation délivrée au Consumer
  5. Service Provider : vérifie l'Authorization Code puis octroi un Access Token au Consumer
  6. Consumer : utilise l'Access Token pour accéder aux données protégées de l'utilisateur

Pour transmettre l'Access Token, une méthode courante est d'utiliser un en-tête HTTP Authorization de type Bearer :

Authorization: Bearer 3aa5120c-1e54-91a1-4718-5e6412715bc2

L'Access Token n'est pas chiffré, la sécurité repose sur l'utilisation de TLS et sur des paramètres anti-CSRF.

Vous pouvez lire OAuth 2 Simplified ou An Introduction to OAuth 2 pour davantage d'informations.

OpenID Connect

Théoriquement, OAuth 2.0 est un protocole d'autorisation. Cependant, il est possible de l'utiliser pour construire un mécanisme d'authentification, par exemple en considérant l'identité d'un utilisateur comme une ressource. La façon d'implémenter un tel mécanisme est laissée libre au développeur.

OpenID Connect vient combler ce vide en proposant un standard IdP permettant de déléguer l'identification et l'authentification d'un utilisateur via l'ajout d'une couche au-dessus du protocole OAuth 2.0.

Voici quelques-unes de ses caractéristiques :

  • il fonctionne en mode REST et les données échangées sont au format JSON
  • il ajoute le concept d'ID token, un jeton sécurisé contenant l'identité de l'utilisateur au format JSON
  • il standardise certains endpoints comme UserInfo qui fournit un certain nombre d'informations à propos d'un utilisateur connecté

Vous pouvez lire OpenID Connect explained pour une introduction détaillée.

Vous pouvez aussi aller lire Securing the Login with OAuth 2 and OpenID Connect pour voir un exemple d'implémentation en NodeJS des parties serveur et client des protocoles OAuth 2.0 et OpenID Connect.