Comprendre les types d'autorisation (Grant Types) OpenID Connect et OAuth2

OpenID Connect

Dans le monde numérique d’aujourd’hui, la sécurisation des applications web et des API est essentielle pour protéger les données des utilisateurs et empêcher les accès non autorisés. OAuth2 et OpenID Connect sont deux protocoles d’authentification et d’autorisation populaires qui permettent un accès sécurisé aux applications web et aux API. Les deux protocoles définissent différents types d’autorisation (grant types) qui dictent comment les jetons d’accès (access tokens) sont obtenus et utilisés pour accéder aux ressources protégées. Comprendre ces types d’autorisation et leurs cas d’utilisation est crucial pour concevoir des applications sécurisées et fiables. Dans cet article, nous explorerons les différents grant types OAuth2 et OpenID Connect, leurs différences et quand les utiliser.

Choisir le bon type d’autorisation (Grant Type) OAuth2/OpenID Connect pour votre cas d’utilisation

Lorsqu’il s’agit de sélectionner le grant type OAuth2/OpenID Connect approprié pour une application, plusieurs facteurs doivent être pris en compte. Le bon choix dépend des exigences de sécurité spécifiques, du type de client (SPA, mobile, TV, …) et de l’expérience utilisateur que vous souhaitez offrir à vos utilisateurs.

Si vous avez besoin d’aide pour créer votre client, vous pouvez utiliser notre assistant de création de client OAuth 2.0 pour vous guider en plus des explications fournies ci-dessous.

Application Web et Mobile

Si vous développez une application web qui nécessite l’authentification de l’utilisateur, le flux de code d’autorisation (Authorization Code Flow) avec l’extension PKCE est un excellent choix. Il offre un niveau de sécurité plus élevé en exigeant que l’utilisateur s’authentifie directement auprès du serveur d’autorisation, et il permet également l’utilisation de jetons de renouvellement (refresh tokens) pour maintenir une session plus longue.

Machine à Machine (Machine To Machine - M2M)

Le type d’autorisation d’identifiants de client (Client Credentials) est généralement plus adapté aux scénarios de machine à machine (M2M), par exemple lors de l’exécution de tâches automatisées ou de processus en arrière-plan. Il permet au client de s’authentifier lui-même à l’aide d’un secret partagé, tel qu’un identifiant client (client ID) et un secret (client secret). Cette approche est plus sécurisée que l’utilisation des identifiants d’un utilisateur, car elle évite d’avoir à stocker et à transmettre des informations utilisateur sensibles.

IoT et Smart TV

Sur un appareil IoT ou une Smart TV, vous n’avez parfois pas d’interface utilisateur pour saisir des identifiants de connexion, ce qui rend difficile l’obtention d’un jeton d’accès. Le type d’autorisation pour appareil connecté (Device Authorization Grant) est conçu spécifiquement pour ces scénarios où l’appareil est incapable de gérer les interactions utilisateur directes. À la place, il fournit un code unique à l’utilisateur qu’il peut saisir sur un autre appareil, comme un smartphone ou un ordinateur, afin d’autoriser l’appareil à accéder à ses données en son nom.

Flux de Code d’Autorisation (Authorization Code Flow)

datatracker.ietf.org/doc/html/rfc6749#section-1.3.1

Le flux de code d’autorisation (Authorization Code Flow) est l’un des grant types OAuth2 les plus couramment utilisés. Il est généralement employé lorsqu’un utilisateur doit accorder l’accès à ses ressources à une application ou un service web ou mobile tiers.

Dans ce flux, l’utilisateur est redirigé vers la page de connexion du serveur d’autorisation, où il doit s’authentifier et autoriser l’accès de l’application à ses ressources. Une fois que l’utilisateur a accordé l’autorisation, le serveur d’autorisation renvoie un code d’autorisation à l’application.

L’application échange ensuite le code d’autorisation contre un jeton d’accès (access token) et un jeton de renouvellement (refresh token) en envoyant une requête au point de terminaison de jeton (token endpoint) du serveur d’autorisation. Ce jeton d’accès peut être utilisé pour accéder aux ressources protégées de l’utilisateur pendant une période spécifiée.

Le flux de code d’autorisation est considéré comme plus sécurisé que d’autres grant types comme le flux implicite (implicit flow), car il nécessite que le client stocke le secret client en toute sécurité et ne l’envoie au serveur d’autorisation que via un canal sécurisé. Il garantit également que les identifiants de l’utilisateur ne sont pas exposés au client, puisqu’ils ne sont gérés que par le serveur d’autorisation pendant le processus de connexion.

Voici un exemple de requêtes pour le flux de code d’autorisation :

  1. L’application cliente redirige l’utilisateur vers le point de terminaison d’autorisation du serveur d’autorisation avec les paramètres requis, notamment l’identifiant du client (client ID), l’URI de redirection, le type de réponse défini sur code, et la portée (scope).
GET /authorize?response_type=code&client_id=abcd1234&redirect_uri=https://mydomain.com/callback&scope=<scopes>&state=<state>&nonce=<nonce> HTTP/1.1
Host: authorization-server.com

Voici quelques explications sur les paramètres de requête utilisés dans la demande de flux de code d’autorisation :

  • response_type : Spécifie le type de réponse souhaité. Pour le flux de code d’autorisation, cette valeur est définie sur code.
  • client_id : L’identifiant unique de l’application cliente.
  • redirect_uri : L’URI vers laquelle le serveur d’autorisation redirigera l’utilisateur après l’autorisation.
  • scope : Une liste de portées (scopes) séparées par des espaces qui spécifient le niveau d’accès demandé.
  • state : Une valeur opaque utilisée pour maintenir l’état entre la requête et le callback. Elle est utilisée pour empêcher les attaques CSRF.
  • nonce : Une valeur aléatoire utilisée pour empêcher les attaques par rejeu dans OpenID Connect.
  1. L’utilisateur s’authentifie et autorise l’application cliente à accéder à ses ressources.
  2. Le serveur d’autorisation redirige l’utilisateur vers l’URI de redirection de l’application cliente avec un code d’autorisation.
GET /callback?code=<authorization_code>&state=<state> HTTP/1.1
Host: mydomain.com
  1. Le client vérifie le paramètre state pour empêcher les attaques CSRF et s’assure que le code d’autorisation est valide.

  2. L’application cliente échange le code d’autorisation contre un jeton d’accès et un jeton de renouvellement en envoyant une requête au point de terminaison de jeton du serveur d’autorisation.

POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=<authorization_code>
&redirect_uri=https://mydomain.com/callback
&client_id=abcd1234
&client_secret=<client_secret>

Ce flux est recommandé pour les applications côté serveur où le secret client peut être stocké en toute sécurité et n’est pas facilement accessible par des attaquants potentiels. Pour les clients publics comme les applications monopages (SPA) ou les applications mobiles, le flux de code d’autorisation avec l’extension PKCE est recommandé.

Extension PKCE

datatracker.ietf.org/doc/html/rfc7636

PKCE (prononcé “pixie”), pour Proof Key for Code Exchange (clé de preuve pour l’échange de code), est une extension du flux de code d’autorisation OAuth2 qui offre une sécurité accrue contre les attaques par interception de code. Il est conçu pour protéger les clients publics, tels que les applications mobiles et les applications monopages, qui ne peuvent pas garder confidentiel le secret d’un client. PKCE ajoute un secret unique, appelé vérificateur de code (code verifier), à la demande d’autorisation. Le serveur d’autorisation répond avec un défi de code (code challenge), qui est une version hachée du vérificateur de code. Le client échange ensuite le code et le vérificateur de code contre un jeton d’accès. PKCE est largement utilisé dans les implémentations OAuth2 modernes et est considéré comme une bonne pratique pour sécuriser les clients publics.

Vous pouvez en savoir plus sur PKCE dans notre article dédié : Qu’est-ce que PKCE et pourquoi devriez-vous l’utiliser ?

Flux d’Identifiants de Client (Client Credentials Flow)

datatracker.ietf.org/doc/html/rfc6749#section-4.4

Le flux d’identifiants de client (Client Credentials Flow) est utilisé lorsqu’une application cliente doit accéder à des ressources qu’elle possède ou contrôle, sans aucune implication de l’utilisateur. Ce flux est adapté à la communication de machine à machine (M2M), comme l’accès à des API à partir d’un serveur back-end.

Dans ce flux, l’application cliente envoie ses propres identifiants (identifiant client et secret) directement au serveur d’autorisation. Le serveur d’autorisation vérifie les identifiants du client et délivre un jeton d’accès à l’application cliente.

Le flux d’identifiants de client comprend les étapes suivantes :

  1. L’application cliente envoie une requête au serveur d’autorisation avec son propre identifiant client et secret, ainsi que le paramètre de type d’autorisation défini sur client_credentials.
  2. Le serveur d’autorisation valide les identifiants du client et génère un jeton d’accès.
  3. Le serveur d’autorisation renvoie le jeton d’accès à l’application cliente.
  4. L’application cliente utilise le jeton d’accès pour accéder aux ressources protégées sur le serveur de ressources.

Voici un exemple de requête pour le flux d’identifiants de client :

POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=abcd1234
&client_secret=<client_secret>

Le flux d’identifiants de client est utile lorsque l’application cliente doit accéder à ses propres ressources sans impliquer un utilisateur dans le processus. Cependant, il ne doit pas être utilisé si le serveur de ressources a besoin de connaître l’identité de l’utilisateur accédant à la ressource. Dans ces cas, le flux de code d’autorisation ou un autre flux approprié doit être utilisé à la place.

Type d’Autorisation de Jeton de Renouvellement (Refresh Token Grant Type)

datatracker.ietf.org/doc/html/rfc6749#section-1.5

Le type d’autorisation de jeton de renouvellement (Refresh Token) est utilisé pour obtenir une nouvelle paire de jeton d’accès et de jeton de renouvellement en utilisant un jeton de renouvellement qui a été précédemment délivré au client. Ce flux est utile lorsqu’un jeton d’accès a expiré ou est sur le point d’expirer et que le client doit en obtenir un nouveau sans lancer un nouveau processus d’autorisation complet impliquant l’utilisateur.

Dans ce flux, le client envoie une requête au serveur d’autorisation avec le paramètre grant_type défini sur refresh_token et inclut le jeton de renouvellement précédemment délivré. Le serveur d’autorisation vérifie ensuite le jeton de renouvellement et délivre une nouvelle paire de jeton d’accès et de jeton de renouvellement.

Les jetons de renouvellement ont généralement une durée de vie plus longue que les jetons d’accès et peuvent être révoqués indépendamment de ces derniers. Cela les rend utiles pour maintenir des sessions de longue durée et offrir une meilleure expérience utilisateur.

Il est important de noter que l’utilisation de jetons de renouvellement introduit des considérations de sécurité supplémentaires, car ils représentent des identifiants à longue durée de vie qui peuvent être utilisés pour obtenir des jetons d’accès sans exiger de l’utilisateur qu’il se réauthentifie. Par conséquent, les jetons de renouvellement doivent être protégés de manière appropriée et ne doivent être délivrés qu’à des clients de confiance qui ont été correctement authentifiés et autorisés.

Le type d’autorisation Refresh Token doit être utilisé dans les scénarios où le client a besoin d’obtenir un nouveau jeton d’accès sans intervention de l’utilisateur, et où l’utilisation de clés d’accès à longue durée de vie est acceptable et correctement sécurisée.

Mécanisme de Rotation des Jetons de Renouvellement (Rotating Refresh Token)

Le mécanisme de rotation des jetons de renouvellement est une fonctionnalité de sécurité qui aide à prévenir l’abus à long terme des jetons de renouvellement. Il consiste à émettre un nouveau jeton de renouvellement en même temps qu’un nouveau jeton d’accès chaque fois qu’un jeton de renouvellement est utilisé. Le nouveau jeton de renouvellement invalide le précédent, et le processus se répète chaque fois qu’un nouveau jeton de renouvellement est utilisé.

Ce mécanisme garantit que si un jeton de renouvellement est volé, il ne sera valide que pendant une durée limitée, ce qui complique la tâche des attaquants souhaitant l’utiliser pour obtenir un accès non autorisé. Il permet également de détecter et de prévenir les attaques par rejeu, où un attaquant tente d’utiliser un jeton de renouvellement obtenu précédemment pour acquérir de nouveaux jetons d’accès.

Lors de la mise en œuvre de la rotation des jetons de renouvellement, il est important de trouver un équilibre entre sécurité et convivialité. Si les jetons de renouvellement expirent trop rapidement, les utilisateurs devront peut-être se réauthentifier fréquemment, ce qui peut être frustrant. D’un autre côté, si la durée de vie des jetons de renouvellement est trop longue, le risque d’abus en cas de vol est plus élevé.

Autorisation pour Appareil Connecté (Device Authorization Grant)

datatracker.ietf.org/doc/html/rfc8628#section-3.4

Le type d’autorisation pour appareil connecté (Device Authorization Grant, également connu sous le nom de Device Flow) a été introduit dans OAuth2.1 et est conçu pour les appareils dépourvus de navigateur web, comme une TV ou une console de jeux, afin d’obtenir un jeton d’accès. Dans ce flux, l’utilisateur visite un point de terminaison d’autorisation spécial sur un autre appareil, tel qu’un téléphone mobile ou un ordinateur portable, pour lancer le processus d’autorisation. L’appareil nécessitant l’autorisation affiche alors un message contenant un code unique et des instructions pour que l’utilisateur saisisse ce code sur l’autre appareil.

Le serveur d’autorisation interroge régulièrement (polling) l’état de l’autorisation de l’appareil et, une fois autorisé, renvoie un jeton d’accès à l’appareil. Ce flux peut également inclure un jeton de renouvellement.

Le type d’autorisation Device Authorization Grant est utile dans les situations où un utilisateur ne peut pas saisir directement ses identifiants sur l’appareil nécessitant l’autorisation, ou lorsque l’appareil ne dispose pas de la capacité d’afficher un écran de connexion. Cependant, il convient de noter que ce flux peut introduire des risques de sécurité, car l’utilisateur peut ne pas être pleinement conscient de l’étendue des autorisations qu’il accorde à l’appareil. Comme pour tout type d’autorisation OAuth2, il ne doit être utilisé que dans les situations appropriées et sécurisées.

Flux d’Assertion Utilisateur avec le Type d’Autorisation JWT-Bearer

datatracker.ietf.org/doc/html/rfc7523

Dans OAuth2, le flux d’assertion utilisateur (User Assertion Flow) est un mécanisme qui permet à une application cliente d’authentifier un utilisateur et d’obtenir un jeton d’accès en son nom en utilisant un jeton JSON Web (JWT) ou une assertion SAML. Le type d’autorisation urn:ietf:params:oauth:grant-type:jwt-bearer est spécifiquement conçu à cet effet.

Comment ça fonctionne

Le flux d’assertion utilisateur avec le type d’autorisation JWT-Bearer comprend généralement les étapes suivantes :

  1. Authentification de l’utilisateur : L’application cliente authentifie l’utilisateur à l’aide d’un mécanisme externe à OAuth2, tel qu’un formulaire de connexion, une authentification sociale ou un processus d’authentification multifacteur. Une fois l’utilisateur authentifié, l’application cliente obtient un JWT représentant son identité.
  2. Création du JWT : L’application cliente crée un JWT en utilisant les informations d’authentification de l’utilisateur comme assertion. Le JWT est généralement signé à l’aide de la clé privée du client pour garantir son intégrité.
  3. Demande de jeton : L’application cliente envoie une requête de jeton au point de terminaison de jeton du serveur d’autorisation, en incluant le JWT comme assertion utilisateur dans le corps de la requête, ainsi que les autres paramètres requis tels que le type d’autorisation (urn:ietf:params:oauth:grant-type:jwt-bearer), l’identifiant du client et la portée.
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&scope=<scopes>
&assertion=<jwt>
  1. Validation de l’assertion : Le serveur d’autorisation reçoit la demande de jeton et valide l’assertion utilisateur du JWT. Cela consiste généralement à vérifier la signature du JWT à l’aide de la clé publique du client, à contrôler sa date d’expiration et à vérifier toute autre revendication (claim) ou attribut pertinent.
  2. Émission du jeton d’accès : Si l’assertion utilisateur du JWT est valide, le serveur d’autorisation émet un jeton d’accès ou d’autres jetons, tels qu’un jeton de renouvellement, représentant l’autorisation de l’utilisateur. L’application cliente peut alors utiliser le jeton d’accès pour accéder aux ressources protégées au nom de l’utilisateur.

Lors de l’implémentation du flux d’assertion utilisateur avec le type d’autorisation JWT-Bearer, il convient de garder à l’esprit une considération importante. Comme pour tout flux OAuth2, la sécurité est primordiale. Le JWT utilisé comme assertion utilisateur doit être correctement sécurisé, y compris par des mécanismes de signature et de chiffrement appropriés, afin de garantir son intégrité et sa confidentialité.

Type d’Autorisation d’Échange de Jetons (Token Exchange Grant Type)

datatracker.ietf.org/doc/html/rfc8693

Le type d’autorisation d’échange de jetons (Token Exchange) permet à une entité (appelée l’« acteur ») d’échanger un jeton contre un autre jeton avec un ensemble différent de permissions ou de portées (scopes). L’acteur peut être une application cliente ou un utilisateur. Ce type d’autorisation permet la délégation d’accès et offre un contrôle précis sur les permissions accordées à un jeton.

Ce type d’autorisation est utilisé avec la valeur urn:ietf:params:oauth:grant-type:token-exchange et implique l’échange d’un jeton existant contre un nouveau jeton avec des portées et des audiences différentes. L’échange est facilité en soumettant une requête d’échange de jeton au point de terminaison de jeton du serveur d’autorisation.

POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&client_id=abcd1234
&client_secret=<client_secret>
&scope=<scopes>
&subject_token=<access_token>
&subject_token_type=urn:ietf:params:oauth:token-type:access_token

Autorisation Implicite (Implicit Grant)

datatracker.ietf.org/doc/html/rfc6749#section-1.3.2

Le flux implicite (Implicit flow) est un type d’autorisation d’accès OAuth2 initialement conçu pour les applications côté client s’exécutant dans un navigateur, telles que les applications monopages (SPA). Ce flux visait à simplifier le processus d’authentification côté client en éliminant la nécessité d’un composant côté serveur pour gérer le secret du client.

Cependant, le flux implicite présente d’importantes failles de sécurité et son utilisation n’est plus recommandée par la spécification OAuth2. L’un des problèmes les plus graves du flux implicite est qu’il renvoie le jeton d’accès directement à l’application côté client sous la forme d’un identifiant de fragment dans l’URL. Cela signifie que le jeton d’accès est exposé à l’application côté client et peut être facilement intercepté par un acteur malveillant.

Un autre problème lié au flux implicite est qu’il ne prend pas en charge les jetons de renouvellement (refresh tokens), utilisés pour obtenir un nouveau jeton d’accès à l’expiration du premier. Cela implique que l’utilisateur doit se réauthentifier à chaque expiration du jeton d’accès, ce qui altère l’expérience utilisateur.

En résumé, bien que le flux implicite ait été initialement conçu pour simplifier le processus d’authentification côté client, son utilisation est déconseillée en raison de ses vulnérabilités. Il est plutôt recommandé d’utiliser le flux de code d’autorisation avec PKCE, qui offre un mécanisme d’authentification plus sécurisé et robuste pour les applications côté client fonctionnant dans un navigateur.

Dépréciation de l’Implicit Grant

Ce flux est obsolète (déprécié), vous ne devriez pas l’utiliser. Voici quelques ressources détaillant cette dépréciation :

Type d’Autorisation par Identifiants de Connexion du Propriétaire de la Ressource (Resource Owner Password Credentials Grant - ROPC)

Le type d’autorisation ROPC (Resource Owner Password Credentials) permet à une application d’obtenir directement le nom d’utilisateur et le mot de passe de l’utilisateur final pour les échanger contre un jeton d’accès. Ce type d’autorisation est souvent utilisé pour les systèmes hérités (legacy) ou lorsque d’autres grant types ne sont pas envisageables.

Cependant, l’utilisation de ROPC introduit d’importants risques de sécurité. Tout d’abord, l’application doit stocker les identifiants de l’utilisateur final, ce qui représente un risque majeur pour la sécurité si l’application est compromise. De plus, ROPC enfreint le principe de séparation des préoccupations qui est un élément clé d’OAuth 2.0.

Le ROPC ne doit pas être utilisé. Il convient de noter que certains fournisseurs OpenID Connect ne prennent pas du tout en charge le ROPC, car il est considéré comme une option peu sécurisée.

Dans l’ensemble, il est recommandé d’utiliser d’autres types d’autorisation chaque fois que cela est possible afin d’assurer un flux d’authentification plus sûr et plus robuste.

Dépréciation du Resource Owner Password Credentials Grant

Ce flux est obsolète (déprécié), vous ne devriez pas l’utiliser. Voici quelques ressources détaillant cette dépréciation :

Section sur ROPC dans les bonnes pratiques de sécurité OAuth 2.0

Flux Hybride OpenID Connect (Hybrid Flow)

https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth

Le flux hybride OpenID Connect (Hybrid Flow) combine le flux de code d’autorisation et le flux implicite. Ce flux est conçu pour les applications nécessitant l’accès aux informations de l’utilisateur, et il est recommandé lorsque l’application cliente est une application web s’exécutant côté serveur.

Le flux hybride fonctionne d’abord en envoyant l’utilisateur vers le serveur d’autorisation pour s’authentifier et autoriser l’application, comme dans le flux de code d’autorisation. Une fois que l’utilisateur a authentifié et autorisé l’application, le serveur d’autorisation renvoie un code d’autorisation à l’application.

L’application utilise ensuite le code d’autorisation pour récupérer un jeton d’accès auprès du serveur d’autorisation, à l’instar du flux de code d’autorisation. Cependant, en plus du jeton d’accès, le serveur d’autorisation renvoie également un jeton d’identité (ID token), de la même manière que pour le flux implicite.

Le jeton d’identité contient des informations sur l’utilisateur, telles que son nom et son adresse e-mail, au format JSON Web Token (JWT). Cela permet à l’application d’authentifier l’utilisateur et d’accéder à ses informations sans avoir à effectuer d’appels API supplémentaires.

Ressources