Flux de la plateforme d’identités Microsoft et d’octroi implicite OAuth 2.0
La plateforme d’identités Microsoft prend en charge le flux d’octroi implicite OAuth 2.0, comme cela est décrit dans la spécification OAuth 2.0. La définition de l’octroi implicite stipule que les jetons (jetons d’ID ou jetons d’accès) sont retournés directement à partir du point de terminaison /authorize au lieu du point de terminaison /token. Cette méthode est souvent utilisée dans le cadre du flux du code d’autorisation, dans ce que l’on appelle le « flux hybride », qui récupère le jeton d’ID sur la demande /authorize avec un code d’autorisation.
Cet article explique comment programmer directement par rapport au protocole dans votre application pour demander des jetons à Microsoft Entra ID. Dans la mesure du possible, nous vous recommandons d’utiliser les bibliothèques d’authentification Microsoft (MSAL) prises en charge au lieu d’acquérir des jetons et d’appeler des API web sécurisées. Pour obtenir la liste des exemples de code qui utilisent MSAL, reportez-vous aux exemples de code Plateforme d’identités Microsoft.
Avertissement
Microsoft vous recommande de ne pas utiliser le flux d’octroi implicite. Dans la plupart des scénarios, des alternatives plus sécurisées sont disponibles et recommandées. Certaines configurations de ce flux nécessitent un degré de confiance très élevé dans l’application et comporte des risques qui ne sont pas présents dans d’autres flux. Utilisez ce flux uniquement lorsqu’aucun autre flux plus sécurisé n’est viable. Pour plus d’informations, consultez les problèmes de sécurité liés au flux d’octroi implicite.
Schéma de protocole
Le diagramme suivant montre à quoi ressemble le flux implicite de connexion complet. Les sections qui suivent décrivent chaque étape en détail.
Scénarios adaptés à l’octroi implicite OAuth2
L’octroi implicite n'est fiable que pour la partie initiale et interactive de votre flux de connexion, où l’absence de cookies tiers n’impacte pas votre application. Cette limitation signifie que vous devez l’utiliser exclusivement dans le cadre du flux hybride, où votre application demande un code ainsi qu’un jeton auprès du point de terminaison d’autorisation. Dans un flux hybride, votre application reçoit un code qui peut être échangé contre un jeton d’actualisation, et la session de connexion de votre application reste ainsi valide dans le temps.
Privilégier le flux du code d’authentification
Certains navigateurs ayant abandonné le support des cookies tiers, le flux d’autorisations implicites devient inadapté comme méthode d’authentification. Les fonctionnalités d’authentification unique (SSO) silencieuse du flux implicite ne fonctionnent pas sans cookies tiers, ce qui entraîne le blocage des applications qui tentent d'obtenir un nouveau jeton. Nous recommandons vivement que toutes les nouvelles applications utilisent le flux du code d'autorisation qui prend désormais en charge les applications monopages au lieu du flux implicite. Les applications monopages existantes doivent également migrer vers le flux du code d’autorisation.
Problèmes de sécurité liés au flux d’octroi implicite
Le flux d’octroi implicite est destiné aux applications web traditionnelles où le serveur contrôle le traitement sécurisé des données POST. Il existe deux façons principales de fournir des jetons avec le flux d’octroi implicite : où response_mode
est retourné en tant que fragment d’URL ou en tant que paramètre de requête (utilisation form POST
et GET
). Dans le flux implicite où response_mode=form_post
, le jeton est remis en toute sécurité via un formulaire HTML POST à l’URI de redirection du client. Cette méthode garantit que le jeton n’est pas exposé dans le fragment d’URL, ce qui évite à son tour les risques de fuite de jetons via l’historique du navigateur ou les en-têtes de référent.
Les problèmes de sécurité liés au flux implicite se produisent lorsque les jetons sont remis à l’aide de response_mode=fragment
. Le fragment d’URL fait partie de l’URL qui vient après le symbole #
et n’est pas envoyé au serveur lorsque le navigateur demande une nouvelle page, mais est disponible pour JavaScript s’exécutant dans le navigateur. Cela signifie que le jeton est exposé à n’importe quel code JavaScript en cours d’exécution sur la page, ce qui peut constituer un risque de sécurité si la page inclut des scripts tiers. Ces problèmes de sécurité pour les jetons dans les SPA ne s’appliquent pas non plus au flux implicite avec form POST
.
Quand devez-vous autoriser l’émission d’un jeton d’ID ou d’un jeton d’accès lors d’une demande utilisant un octroi implicite ou un flux hybride ?
L’octroi implicite et le flux hybride ne sont pas aussi sécurisés que d’autres flux OAuth. Sauf en cas d’absolue nécessité, vous ne devez pas autoriser l’émission d’un jeton d’accès ou d’ID lors d’une demande utilisant un octroi implicite ou un flux hybride dans votre inscription d’application. Si vous (ou vos développeurs) utilisez MSAL dans votre application pour implémenter l’authentification et l’autorisation, aucun des champs ne doit être activé.
Toutefois, si vous (ou vos développeurs) n’utilisez pas MSAL dans votre application, veuillez consultez le tableau suivant pour déterminer quand des jetons d’accès ou un jeton d’ID doivent être activés.
Type d’application que vous générez | Jetons que vous devez activer dans l’inscription d’application |
---|---|
Une SPA (application monopage) qui n’utilise pas le flux de code d’autorisation avec PKCE | Jetons d’accès et jetons d’ID |
Une application SPA ou web qui appelle une API web via JavaScript en utilisant un flux implicite | Jetons d’accès et jetons d’ID |
Une application web ASP.NET Core et d’autres applications web qui utilisent une authentification hybride | Jetons d’ID |
Envoyer la requête de connexion
Pour connecter une première fois l’utilisateur à votre application, vous pouvez envoyer une demande d’authentification OpenID Connect et obtenir un jeton id_token
à partir de la plateforme d’identités Microsoft.
Important
Pour demander un jeton d’ID ou d’accès avec succès, le flux d’octroi implicite correspondant à l’inscription d’application sur la page Inscriptions d’applications du centre d’administration Microsoft Entra doit être activé. Pour ce faire, sélectionnez Jetons d’ID et Jetons d’accès dans la section Octroi implicite et flux hybrides. S’il n’est pas activé, une erreur unsupported_response
est retournée :
The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
Paramètre | Type | Description |
---|---|---|
tenant |
requis | La valeur {tenant} dans le chemin d’accès de la requête peut être utilisée pour contrôler les utilisateurs qui peuvent se connecter à l’application. Les valeurs autorisées sont common , organizations , consumers et les identifiants du client. Pour plus d’informations, consultez les principes de base du protocole. Notez que, dans les scénarios d’invités, où vous connectez l’utilisateur d’un client à un autre client, vous devez impérativement fournir l’identifiant du client pour connecter correctement l’utilisateur au client des ressources. |
client_id |
requis | ID d’application (client) que la page Inscriptions d’applications du centre d’administration Microsoft Entra a attribué à votre application. |
response_type |
requis | Doit inclure id_token pour la connexion à OpenID Connect. Il peut également inclure le response_type , token . L’utilisation de l’élément token permet ici à votre application de recevoir immédiatement un jeton d’accès à partir du point de terminaison d’autorisation sans avoir à exécuter une deuxième requête sur le point de terminaison d’autorisation. Si vous utilisez l’élément response_type token , le paramètre scope doit contenir une étendue indiquant la ressource pour laquelle le jeton doit être émis (par exemple, user.read sur Microsoft Graph). Il peut également contenir la ressource code au lieu de token pour fournir un code d’autorisation à utiliser dans le flux du code d’autorisation. Cette réponse id_token +code est parfois appelée « flux hybride ». |
redirect_uri |
recommandé | URI de redirection de votre application, où votre application envoie et reçoit des réponses d’authentification. Il doit correspondre exactement à l’un des URI de redirection enregistrés dans le centre d’administration Microsoft Entra, à l’exception qu’il doit être codé au format URL. |
scope |
requis | Une liste d’étendues séparées par des espaces. Pour OpenID Connect (id_tokens ), vous devez inclure l’étendue openid qui correspond à l’autorisation « Connexion » dans l’interface utilisateur de consentement. Vous pouvez également inclure les étendues email et profile permettant d’accéder à des données utilisateur supplémentaires. Vous pouvez aussi inclure d’autres étendues dans cette requête pour solliciter le consentement sur diverses ressources, si un jeton d’accès est demandé. |
response_mode |
recommandé | Spécifie la méthode à utiliser pour envoyer le jeton résultant à votre application. Par défaut query simplement un jeton d’accès, mais fragment si la requête inclut un jeton id_token. Pour des raisons de sécurité, il est recommandé d’utiliser form_post pour le flux implicite pour s’assurer que le jeton n’est pas exposé dans le fragment d’URL. |
state |
recommandé | Valeur incluse dans la demande qui également renvoyée dans la réponse du jeton. Il peut s’agir d’une chaîne du contenu de votre choix. Une valeur unique générée de manière aléatoire est généralement utilisée pour empêcher les attaques de falsification de requête intersite. La valeur d’état est également utilisée pour coder les informations sur l’état de l’utilisateur dans l’application avant la requête d’authentification, comme la page ou l’écran sur lequel ou laquelle il était positionné. |
nonce |
requis | Valeur incluse dans la demande, générée par l’application, qui est incluse dans le jeton d’ID résultant en tant que revendication. L’application peut ensuite vérifier cette valeur afin de contrer les attaques par rejeu de jetons. La valeur est généralement une chaîne unique et aléatoire qui peut être utilisée pour identifier l’origine de la requête. Obligatoire uniquement quand un id_token est demandé. |
prompt |
facultatif | Indique le type d’interaction utilisateur requis. Les seules valeurs valides pour l’instant sont login , none , select_account et consent . prompt=login force l’utilisateur à saisir ses identifiants lors de cette requête, annulant de fait l’authentification unique. prompt=none représente l’inverse. Cela permet de garantir que l’utilisateur ne se voit pas proposer d’invite interactive. Si la requête ne peut pas être exécutée en mode silencieux au moyen d’une authentification unique, la plateforme d’identités Microsoft renvoie une erreur. prompt=select_account envoie l’utilisateur vers un sélecteur de compte dans lequel tous les comptes mémorisés dans la session seront affichés. prompt=consent déclenche l’affichage de la boîte de dialogue de consentement OAuth après la connexion de l’utilisateur, afin de lui demander d’accorder des autorisations à l’application. |
login_hint |
facultatif | Vous pouvez utiliser ce paramètre pour remplir au préalable le champ réservé au nom d’utilisateur et à l’adresse e-mail de la page de connexion de l’utilisateur(-trice) si vous connaissez déjà son nom d’utilisateur. Les applications utilisent souvent ce paramètre durant la réauthentification, après avoir extrait la revendication facultative login_hint à partir d’une connexion antérieure. |
domain_hint |
facultatif | S’il est inclus, ce paramètre ignore le processus de découverte par e-mail auquel l’utilisateur doit se soumettre sur la page de connexion, ce qui améliore légèrement l’expérience utilisateur. Ce paramètre est couramment utilisé pour les applications coeur de métier qui fonctionnent dans un client unique, où l’utilisateur fournit un nom de domaine dans un client donné, ce qui transfère l’utilisateur vers le fournisseur de fédération pour ce client. Cette méthode empêche les invités de se connecter à cette application et limite l’utilisation des identifiants cloud comme FIDO. |
À ce stade, l’utilisateur est invité à saisir ses identifiants et à exécuter l’authentification. La plateforme d’identités Microsoft s’assure également que l’utilisateur a accepté les autorisations indiquées dans le paramètre de requête scope
. Si l’utilisateur n’a accepté aucune de ces autorisations, il lui demande de consentir aux autorisations requises. Pour obtenir plus d’informations, consultez Autorisations, consentement et applications multi-locataire.
Une fois que l’utilisateur a procédé à l’authentification et accordé son consentement, la plateforme d’identités Microsoft retourne une réponse à votre application à l’URI redirect_uri
indiqué à l’aide de la méthode spécifiée dans le paramètre response_mode
.
Réponse correcte
Une réponse correcte utilisant response_mode=fragment
et response_type=id_token+code
ressemble à ceci (des sauts de ligne sont ici insérés pour une meilleure lisibilité) :
GET https://localhost/myapp/#
code=0.AgAAktYV-sfpYESnQynylW_UKZmH-C9y_G1A
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
Paramètre | Description |
---|---|
code |
Inclus si response_type inclut code . C’est un code d’autorisation pouvant être utilisé dans le flux du code d’autorisation. |
access_token |
Inclus si response_type inclut token . Le jeton d'accès que l’application a demandé. Le jeton d’accès ne doit pas être décodé ou inspecté ; il doit être traité comme une chaîne opaque. |
token_type |
Inclus si response_type inclut token . Cette valeur est toujours Bearer . |
expires_in |
Inclus si response_type inclut token . Indique, en secondes, la durée de validité du jeton pour la mise en cache. |
scope |
Inclus si response_type inclut token . Indique une ou plusieurs étendues pour lesquelles la valeur access_token est valide. Peut ne pas inclure toutes les étendues demandées si elles n’étaient pas applicables à l’utilisateur. Par exemple, les étendues Microsoft Entra uniquement qui sont demandées lors d’une connexion avec un compte personnel. |
id_token |
Un JSON Web Token (JWT) signé. L’application peut décoder les segments de ce jeton pour demander des informations sur l’utilisateur qui s’est connecté. L’application peut mettre en cache les valeurs et les afficher, mais elle ne doit pas se reposer sur elles pour les limites d’autorisation ou de sécurité. Pour plus d’informations sur les jetons d’ID, consultez id_token reference . Remarque : Fourni uniquement si l’étendue openid a été demandée et si response_type incluait id_tokens . |
state |
Si un paramètre d’état est inclus dans la demande, la même valeur doit apparaître dans la réponse. L’application doit vérifier que les valeurs state de la requête et de la réponse sont identiques. |
Avertissement
N’essayez pas de valider ou de lire des jetons pour des API dont vous n’êtes pas propriétaire, y compris les jetons de cet exemple, dans votre code. Les jetons associés aux services Microsoft peuvent utiliser un format spécial qui n’est pas validé comme jeton JWT, et peuvent également être chiffrés pour les utilisateurs consommateurs (de comptes Microsoft). Même si la lecture des jetons est un outil utile de débogage et d’apprentissage, n’y associez pas de dépendances dans votre code ou tenez compte des spécificités des jetons qui ne correspondent pas à une API que vous contrôlez.
Réponse d’erreur
Les réponses d’erreur peuvent également être envoyées à l’élément redirect_uri
, de manière à ce que l’application puisse les traiter de manière appropriée :
GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Paramètre | Description |
---|---|
error |
Une chaîne de code d’erreur qui peut être utilisée pour classer les types d’erreurs qui se produisent, et qui peut être utilisée pour intervenir face aux erreurs. |
error_description |
Un message d’erreur spécifique qui peut aider un développeur à identifier la cause principale d’une erreur d’authentification. |
Acquérir des jetons d’accès silencieusement
Maintenant que vous avez connecté l’utilisateur dans votre application monopage, vous pouvez obtenir silencieusement des jetons d’accès destinés à appeler des API web sécurisées à l’aide de la plateforme d’identités Microsoft, comme Microsoft Graph. Même si vous avez déjà reçu un jeton utilisant l’élément response_type token
, vous pouvez utiliser cette méthode pour acquérir des jetons vers des ressources supplémentaires sans demander à l’utilisateur de se reconnecter.
Important
Il est peu probable que cette partie du flux implicite fonctionne pour votre application, car elle est utilisée dans différents navigateurs en raison de la suppression des cookies tiers par défaut. Même si cela fonctionne toujours dans les navigateurs basés sur Chromium qui ne sont pas en mode Incognito, les développeurs devraient reconsidérer l’utilisation de cette partie du flux. Dans les navigateurs qui ne prennent pas en charge les cookies tiers, vous recevrez un message d’erreur indiquant qu’aucun utilisateur n’est connecté, car les cookies de session de la page de connexion ont été supprimés par le navigateur.
Dans le flux normal OpenID Connect/OAuth, il vous faut transmettre une demande au point de terminaison /token
de la plateforme d’identités Microsoft. Vous pouvez effectuer la demande dans un iFrame masqué afin d’obtenir de nouveaux jetons pour d’autres API web :
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&response_mode=fragment
&state=12345
&nonce=678910
&prompt=none
&login_hint=myuser@mycompany.com
Pour plus d’informations sur les paramètres de requête dans l’URL, consultez Envoyer la requête de connexion.
Conseil
Essayez de copier et coller la requête suivante dans un onglet de navigateur à l’aide d’une inscription réelle client_id
et username
à partir de l’enregistrement de votre application. Cela vous permet de voir la demande de jeton silencieux en action.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={your-client-id}&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={username}
Notez que cette opération fonctionne même dans les navigateurs sans prise en charge des cookies tiers, puisque vous entrez la requête directement dans une barre de navigateur au lieu de l’ouvrir dans un iFrame.
Grâce au paramètre prompt=none
, cette requête va immédiatement réussir ou échouer, avant de revenir vers votre application. La réponse sera envoyée à votre application, à l’redirect_uri
indiqué, à l’aide de la méthode spécifiée dans le paramètre response_mode
.
Réponse correcte
Une réponse correcte utilisant response_mode=fragment
se présente ainsi :
GET https://localhost/myapp/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fdirectory.read
Paramètre | Description |
---|---|
access_token |
Inclus si response_type inclut token . Jeton d’accès demandé par l’application, dans ce cas Microsoft Graph. Le jeton d’accès ne doit pas être décodé ou inspecté ; il doit être traité comme une chaîne opaque. |
token_type |
Cette valeur est toujours Bearer . |
expires_in |
Indique, en secondes, la durée de validité du jeton pour la mise en cache. |
scope |
Indique une ou plusieurs étendues pour lesquelles le jeton d’accès est valide. Peut ne pas inclure toutes les étendues demandées, si elles n’étaient pas applicables à l’utilisateur (si des étendues Microsoft Entra uniquement sont demandées au moment de la connexion avec un compte personnel). |
id_token |
Un JSON Web Token (JWT) signé. Inclus si response_type inclut id_token . L’application peut décoder les segments de ce jeton pour demander des informations sur l’utilisateur qui s’est connecté. L’application peut mettre en cache les valeurs et les afficher, mais elle ne doit pas se reposer sur elles pour les limites d’autorisation ou de sécurité. Pour en savoir plus sur id_tokens, consultez le document de id_token référence. Remarque : Fourni uniquement si l’étendue openid a été demandée. |
state |
Si un paramètre d’état est inclus dans la demande, la même valeur doit apparaître dans la réponse. L’application doit vérifier que les valeurs state de la requête et de la réponse sont identiques. |
Réponse d’erreur
Les réponses d’erreur peuvent également être envoyées à l’élément redirect_uri
, de manière à ce que l’application puisse les traiter de manière appropriée. Si prompt=none
, une erreur attendue est :
GET https://localhost/myapp/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Paramètre | Description |
---|---|
error |
Une chaîne de code d’erreur qui peut être utilisée pour classer les types d’erreurs qui se produisent, et qui peut être utilisée pour intervenir face aux erreurs. |
error_description |
Un message d’erreur spécifique qui peut aider un développeur à identifier la cause principale d’une erreur d’authentification. |
Si vous recevez cette erreur dans la requête iFrame, l’utilisateur doit se connecter de nouveau de manière interactive, dans le but de récupérer un nouveau jeton. Vous êtes invité à gérer ce cas de la manière la plus appropriée pour votre application.
Actualisation des jetons
L’octroi implicite ne fournit pas de jetons d’actualisation. Les jetons d’ID et d’accès expirant après une courte période, votre application doit être préparée à les actualiser de manière régulière. Pour actualiser l’un ou l’autre des types de jeton, vous pouvez effectuer la même requête iframe masquée que celle mentionnée précédemment à l’aide du paramètre prompt=none
afin de contrôler le comportement de la plateforme d’identités. Si vous souhaitez recevoir un nouveau jeton d’ID, assurez-vous d’utiliser id_token
dans le response_type
et le scope=openid
, ainsi qu’un paramètre nonce
.
Dans les navigateurs qui ne prennent pas en charge les cookies tiers, cela génère une erreur indiquant qu’aucun utilisateur n’est connecté.
Envoi d’une demande de déconnexion
L’élément OpenID Connect end_session_endpoint
permet à votre application d’envoyer une requête à la plateforme d’identités Microsoft pour mettre fin à la session d’un utilisateur et effacer les cookies créés par la plateforme d’identités Microsoft. Pour déconnecter complètement un utilisateur d’une application web, votre application doit mettre fin à sa propre session avec l’utilisateur (généralement en vidant un cache de jeton ou en supprimant les cookies), puis rediriger le navigateur vers :
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout?post_logout_redirect_uri=https://localhost/myapp/
Paramètre | Type | Description |
---|---|---|
tenant |
requis | La valeur {tenant} dans le chemin d’accès de la requête peut être utilisée pour contrôler les utilisateurs qui peuvent se connecter à l’application. Les valeurs autorisées sont common , organizations , consumers et les identifiants du client. Pour plus d’informations, consultez les principes de base du protocole. |
post_logout_redirect_uri |
recommandé | URL vers laquelle l’utilisateur doit être redirigé après la déconnexion. Cette valeur doit correspondre à l’un des URI de redirection inscrits pour l’application. Si elle n’est pas incluse, la plateforme d’identités Microsoft affiche un message générique. |
Voir aussi
- Consultez les exemples JS MSAL pour commencer à coder.
- Vous pouvez utiliser le flux du code d’autorisation comme une alternative plus récente et plus efficace à l’octroi implicite.