OAuth2 est un protocole de délégation d’accès qui décrit comment une application peut accéder à des données au format API de manière sécurisée. Cet accès se limite aux seules données pour lesquelles l’application a obtenu une autorisation et peut faire entrer en jeu l’utilisateur final de l’application s’il s’agit du propriétaire de la donnée.
Aujourd’hui, ce protocole est utilisé massivement, on peut notamment citer :
- Facebook : Documentation
- Github : Documentation
- Google : Documentation
- Stripe : Documentation
- Twitter : Documentation
Les rôles OAuth2
La spécification OAuth2 définit 4 rôles qui peuvent entrer en jeu dans une cinématique d’autorisation :
- Propriétaire de la ressource (Resource Owner) : entité capable de donner l’accès à une ressource protégée. Il peut ainsi s’agir d’une personne, auquel cas il s’agit d’un utilisateur final.
- Serveur de ressource (Resource Server) : serveur qui héberge les données protégées et peut les restituer de manière sécurisée.
- Client : application qui souhaite accéder à des données du serveur de ressource. Il peut par exemple s’agir d’un site web ou d’une application mobile.
- Serveur d’autorisation (Authorization Server) : serveur qui va donner le droit au Client d’accéder au serveur de ressource.
Par exemple, dans le cas où un site web implémente le bouton “Se connecter avec Facebook” :
- Propriétaire de la ressource : utilisateur Facebook qui utilisera le site web.
- Serveur de ressource : Facebook qui possède des informations personnelles sur l’utilisateur tel que son adresse mail, sa photo de profil, etc.
- Client : le site web implémentant le bouton de connexion.
- Serveur d’autorisation : serveur Facebook qui autorise l’accès aux données du serveur de ressource après saisie de ses identifiants et consentement du propriétaire de la ressource.
Gestion des clients OAuth2 (section 2)
Afin de pouvoir autoriser un accès, le serveur d’autorisation a besoin de connaitre l’ensemble des clients pouvant accéder au serveur de ressource.
Ainsi, plusieurs informations sont nécessaires au serveur d’autorisation :
- un nom d’application
- une ou plusieurs URL de redirection
- les types d’authentification que peut utiliser le client
En retour, le serveur d’autorisation fournit au client un identifiant (client_id) ainsi qu’une clé secrète (client_secret).
Les scopes (section 3.3)
Le scope est un paramètre stocké sur le serveur d’autorisation qui permet de limiter les accès au client. Par exemple, un scope peut représenter une donnée ou un groupe de données accessible. Lorsque le client essaye de récupérer un jeton, il doit fournir la liste des scopes qui lui sont nécessaires. Ainsi, plus la liste des scopes est réduite, plus le client a de chances que le propriétaire de la ressource autorise l’accès. De même, la mécanique de scope peut permettre de restreindre la portée d’un appel à une lecture seule.
Par exemple, sur la documentation de Facebook, la liste des scopes que vous pouvez demander est disponible. Chaque scope correspond à une donnée supplémentaire qu’il est possible de récupérer par le client : notamment l’adresse email, la liste des amis, les vidéos de l’utilisateurs, etc.
Les tokens
Lorsque le serveur d’autorisation autorise l’accès à des données à un client, il lui délivre un token (ou jeton). Il s’agit d’une chaine de caractère unique qui permet de retrouver le client et différentes informations nécessaire au processus d’autorisation.
Il existe deux types de tokens / jetons :
- le token d’accès (section 1.4) : il permet au client d’accéder à la ressource protégée. Le serveur d’autorisation limite également la durée de vie du jeton avec une date d’expiration.
- le token de renouvellement (section 1.5) : le serveur d’autorisation le délivre en même temps que le token d’accès. Il sert à renouveler auprès du serveur d’autorisation un token d’accès après expiration de ce dernier. Sa durée de vie est donc plus longue que celle d’un token d’accès. A noter que l’obtention de ce nouveau token d’accès se fait sans l’intervention du propriétaire de la ressource.
Le token de rafraîchissement permet ainsi au client d’obtenir un nouveau token d’accès une fois que celui-ci a expiré. Le token de rafraichissement possède également une durée de vie limité mais plus longue que celle du token d’accès.
Les types d’authentification OAuth2
Authorization Code Grant (section 4.1)
L’authorization code grant est la cinématique OAuth2 que vous utilisez lorsque vous vous connecter avec votre compte Facebook ou Google sur une application.

Authentification de l’utilisateur
Premièrement, le client redirige l’utilisateur vers une page du serveur d’autorisation avec les paramètres suivants :
- response_type :
code
- client_id : l’identifiant du client
- redirect_uri : URL de redirection vers le client. Si non renseigné, l’utilisateur est renvoyé à une des valeurs préenregistrées.
- scope : une liste de scopes séparés par un espace
- state : token CSRF. Ce paramètre est optionnel mais permet de renforcer la sécurité des appels. Le token doit être enregistré dans la session de l’utilisateur pour être vérifié ci-dessous.
Tous ces paramètres sont vérifiés par le serveur d’autorisation. L’utilisateur est alors redirigé vers une page d’authentification du serveur d’autorisation. L’utilisateur doit s’authentifier avec son nom d’utilisateur et son mot de passe puis autoriser l’accès au client.
Si l’utilisateur approuve l’accès, il est alors vers la redirect_uri du client avec les données suivantes :
- code : le code d’autorisation
- state : valorisé avec la valeur de
state
dans la requête originale. Le client doit comparer cette valeur avec celle stockée dans la session de l’utilisateur pour être sûr que le code d’autorisation obtenu est bien celui pour son application.
Récupération du jeton d’accès
Le client peut désormais requêter le serveur d’autorisation avec les paramètres suivants :
- grant_type :
authorization_code
- client_id : l’identifiant du client
- client_secret : le secret du client
- redirect_uri : avec la même URL que celle utilisée lors de la redirection de l’utilisateur
- code : le code d’autorisation renvoyé par le serveur d’autorisation
En réponse, le serveur d’autorisation transmet :
- token_type :
Bearer
- expires_in : nombre de secondes avant que le jeton n’expire
- access_token : le jeton d’accès
- refresh_token : le jeton de renouvellement
Implicit Grant (section 4.2)
L’implicit grant est similaire à l’authorization code grant. Il y a tout de même quelques différences :
- il est destiné aux applications qui ne sont pas en mesure de garder leur secret car tout leur code est accessible. Par exemple, cela peut être le cas d’une application full JS sans serveur.
- le serveur d’autorisation retourne directement un jeton d’accès sans passer par un code d’autorisation.

Authentification de l’utilisateur
Premièrement, le client redirige l’utilisateur vers une page du serveur d’autorisation avec les paramètres suivants :
- response_type :
token
- client_id : l’identifiant du client
- redirect_uri : URL de redirection vers le client. Si non renseigné, l’utilisateur est renvoyé à une des valeurs préenregistrées.
- scope : une liste de scopes séparés par un espace
- state : token CSRF. Ce paramètre est optionnel mais permet de renforcer la sécurité des appels. Le token doit être enregistré dans la session de l’utilisateur pour être vérifié ci-dessous.
L’utilisateur est donc redirigé vers une page d’authentification du serveur d’autorisation. L’utilisateur doit ensuite s’authentifier et autoriser l’accès au client.
Récupération du jeton d’accès
Si l’utilisateur approuve, il est alors redirigé du serveur d’authentification vers le client sur la redirect_uri paramétrée avec les données suivantes :
- token_type :
Bearer
- expires_in : nombre de secondes avant que le jeton n’expire
- access_token : le jeton d’accès
- state : valorisé avec la valeur de
state
dans la requête originale. Le client doit comparer cette valeur avec celle stockée dans la session de l’utilisateur pour être sûr que le code d’autorisation obtenu est bien celui pour son application.
Le serveur d’autorisation ne renvoie pas de jeton de renouvellement car le client ne sera pas en mesure de le garder secret.
Resource Owner Credentials Grant (section 4.3)
Tout d’abord, cette cinématique est utilisable uniquement pour des applications clients tierces pour lesquels le serveur d’autorisation a confiance. En effet, le client est dans ce cas autorisée à récupérer les informations d’identification de l’utilisateur final pour les envoyer directement au serveur d’autorisation. Ainsi, l’utilisateur final n’a pas à s’authentifier sur le serveur d’autorisation mais peut le faire sur l’application du client.

La récupération d’un token se fait par un seul appel. Le client envoie une requête POST au serveur d’autorisation avec les paramètres suivants :
- grant_type :
password
- client_id : l’identifiant du client
- client_secret : le secret du client
- scope : une liste de scopes séparés par un espace
- username : l’identifiant de l’utilisateur
- password : le mot de passe de l’utilisateur
En réponse, le serveur d’autorisation retourne les paramètres suivants :
- token_type :
Bearer
- expires_in : nombre de secondes avant que le jeton n’expire
- access_token : le jeton d’accès
- refresh_token : le jeton de renouvellement
Client Credentials Grant (section 4.4)
Il s’agit du type d’authentification le plus simple. Il est destiné aux communications entre serveurs où l’autorisation de l’utilisateur final n’est pas nécessaire pour accéder aux données. Par exemple, il peut s’agir de l’accès à une API publique où l’authentification de chaque consommateur de l’API permettre au serveur de ressource de mettre en place des limitations.

La récupération d’un token se fait par un seul appel. Le client envoie une requête POST au serveur d’autorisation avec les paramètres suivants :
- grant_type :
client_credentials
- client_id : l’identifiant du client
- client_secret : le secret du client
- scope : une liste de scopes séparés par un espace
En réponse, le serveur d’autorisation retourne les paramètres suivants :
- token_type :
Bearer
- expires_in : nombre de secondes avant que le jeton n’expire
- access_token : le jeton d’accès
Choisir son type d’authentification OAuth2
Vous pouvez choisir votre type d’authentification OAuth2 en vous posant simplement quelques questions.

Propriétaire de la donnée ?
Un jeton représente la permission donné à un client d’accéder à des ressources protégées. Si vous autorisez uniquement une machine à accéder à une ressource sans avoir besoin de la permission de l’utilisateur final, alors vous devez implémenter le Client Credentials Grant.
Si la permission de l’utilisateur final est nécessaire, alors vous devez choisir en fonction du type de client.
Type de client
Le type de client permet de déterminer s’il est capable ou non de garder un secret sans qu’un utilisateur de l’application puisse l’intercepter.
Avec serveur
Si l’application cliente à un serveur pour garder le secret, alors vous devez implémenter l’Authorization Code Grant.
Application native
Si l’application cliente est une application native (comme une application mobile), alors vous devez implémenter :
- le Password Grant si vous avez confiance dans cette application
- l’Authorization Code Grant sinon
Sans serveur
Si l’application cliente n’utilise pas de serveur (c’est le cas par exemple des applications utilisant des framework full JS), alors vous devez implémenter :
- le Password Grant si vous avez confiance dans cette application
- l’Implicit Grant sinon
Client de confiance ?
Un client de confiance est un client à qui vous pouvez déléguer la collecte des informations d’authentification de l’utilisateur final (par exemple son identifiant de connexion et son mot de passe).
Utilisation d’un token
Token d’accès (section 1.4)
Lors de la demand d’accès à une API, le serveur de ressources demande un token d’accès. Cela peut se faire de plusieurs manières :
- en paramètre de la requête (GET OU POST) :
https://api.exemple.fr/ressource?access_token=AbcDEfGhIjKLMnopQRs
- en header de la requête :
Authorization: Bearer AbcDEfGhIjKLMnopQRs
C’est le serveur de ressources qui définit comment est attendu le token d’accès.
Token de renouvellement (section 1.5)
Lorsque le token d’accès a expiré, le client a la possibilité de le renouveler grâce au jeton de renouvellement. Pour ce faire, le client envoie une requête POST au serveur d’autorisation avec les paramètres suivants :
- grant_type :
refresh_token
- refresh_token : le jeton de renouvellement obtenu avec le jeton d’accès
- client_id : l’identifiant du client
- client_secret : le secret du client
- scope : une liste de scopes séparés par un espace
En réponse, le serveur d’autorisation retourne les paramètres suivants :
- token_type :
Bearer
- expires_in : nombre de secondes avant que le jeton n’expire
- access_token : le nouveau jeton d’accès
- refresh_token : le nouveau jeton de renouvellement
Sécurité OAuth2
OAuth2 doit s’utiliser avec une connexion sécurisée via SSL (HTTPS) pour bien remplir son objectif. Il existe également une liste de bonnes pratiques à mettre en place pour que le protocole ne soit pas vulnérables (section 10). Voici quelques exemples de vulnérabilités issues de mises en place incorrect de l’OAuth2.
Implicit Grant
L’attaquant conçoit un site permettant une connexion OAuth2 sur Twitter par exemple. Il récupère donc un jeton d’accès dès qu’une personne s’authentifie via Twitter sur son site. Il peut alors essayer d’utiliser ce jeton d’accès sur un autre site implémentant également la connexion avec Twitter. L’attaquant se retrouve alors en capacité d’usurper le compte de l’utilisateur sur ce site.
Pour contrer cette attaque, les sites implémentant une connexion via Twitter (pour notre exemple) doivent ainsi vérifier que le jeton récupéré a bien été généré pour ce site. Le serveur d’autorisation met donc à disposition une URL permettant de récupérer des informations à partir d’un jeton. Le site attaqué peut donc se rendre compte de la compromission en vérifiant si les informations du jeton sont bien celles attendues.
Clickjacking
L’attaquant conçoit un site où la page d’authentification est masquée et où le bouton de consentement est surchargé par l’affichage d’un autre bouton (par exemple : “Suivant”). Ainsi, l’utilisateur final ne voit que le bouton suivant sans se rendre compte qu’il donne accès à des ressources protégés au site de l’attaquant. Pour mettre en place cette page, l’attaquant doit mettre en place une mécanique de Iframe pour que les pages de notre serveur d’autorisation soit affiché (ou masqué) sur son site.
La solution consiste donc à ne pas autoriser l’utilisation d’Iframe sur des pages de notre serveur d’autorisation. Le header X-Frame-Options doit donc être valorisé avec DENY
(ou SAMEORIGIN
si les iframes peuvent être utilisées par le serveur lui-même uniquement).