Protection des API

Lorsque vous, en tant que développeur, protégez votre API, votre focus est sur l’autorisation. Pour appeler l’API de votre ressource, les applications doivent acquérir l’autorisation d’application. La ressource elle-même doit appliquer l’autorisation. Dans cet article, vous allez découvrir les meilleures pratiques de protection de votre API via l’inscription, la définition des autorisations et le consentement et l’application de l’accès pour atteindre vos objectifs de Confiance Zéro.

Inscription de votre API protégée

Pour protéger votre API avec l’ID Microsoft Entra (Microsoft Entra ID), vous devez d’abord inscrire votre API, après quoi vous pouvez gérer vos API inscrites. Dans l’ID Microsoft Entra, une API est une application avec des paramètres d’inscription d’application spécifiques qui le définissent en tant que ressource ou API qu’une autre application peut être autorisée à accéder. Dans le Centre d’administration Microsoft Entra, Microsoft Identity Developer, Les inscriptions d’applications sont des API qui se trouvent dans le locataire en tant qu’API métier ou services provenant de fournisseurs SaaS disposant d’API protégées par protection des ID Microsoft Entra.

Lors de l’inscription, vous allez définir la façon dont les applications appelantes référencent votre API et ses autorisations déléguées et d’application. Une inscription d’application peut représenter une solution qui possède à la fois des applications clientes et des API. Toutefois, dans cet article, nous aborderons le scénario dans lequel une ressource autonome expose une API.

Normalement, une API n’effectue pas d’authentification ni demande directement l’autorisation. L’API valide un jeton présenté par l’application appelante. Les API n’ont pas de connexions interactives. Vous n’aurez donc pas besoin d’inscrire des paramètres tels que l’URI de redirection ou le type d’application. Les API obtiennent leurs jetons à partir des applications qui appellent ces API, et non en interagissant avec Microsoft Entra ID. Pour les API web, utilisez des jetons d’accès OAuth2 pour l’autorisation. Les API web valident les jetons du porteur pour autoriser les appelants. N’acceptez pas les jetons d’ID comme preuve d’autorisation.

Par défaut, Microsoft Entra ID ajoute User.Read aux autorisations d’API de toute nouvelle inscription d’application. Vous allez supprimer cette autorisation pour la plupart des API web. Microsoft Entra ID nécessite des autorisations d’API uniquement lorsqu’une API appelle une autre API. Si votre API n’appelle pas une autre API, supprimez l’autorisation User.Read lorsque vous inscrivez votre API.

Vous aurez besoin d’un identificateur unique pour votre API, appelé URI d’ID d’application, que les applications clientes qui doivent accéder à votre API demandent l’autorisation d’appeler votre API. L’URI de l’ID d’application doit être unique sur tous les clients Microsoft Entra. Vous pouvez utiliser api://<clientId> (la suggestion par défaut dans le portail), où <clientId> est l’ID d’application de votre API inscrite.

Pour fournir aux développeurs qui appellent votre API avec un nom plus convivial, vous pouvez utiliser l’adresse de votre API comme URI d’ID d’application. Par exemple, vous pouvez utiliser l’emplacement https://API.yourdomain.comyourdomain.com doit être un domaine d’éditeur configuré dans votre client Microsoft Entra. Microsoft valide que vous possédez le domaine pour pouvoir l’utiliser comme identificateur unique pour votre API. Vous n’avez pas besoin de code à cette adresse. L’API peut être là où vous le souhaitez, mais il est recommandé d’utiliser l’adresse HTTPS de l’API comme URI d’ID d’application.

Définition des permissions déléguées avec des privilèges minimum

Si votre API va être appelée par des applications qui ont des utilisateurs, vous devez définir au moins une permission déléguée (voir Ajouter une étendue sur l’inscription d’application Exposer une API).

Les API qui fournissent l’accès aux magasins de données d’organisation peuvent attirer l’attention des attaquants qui souhaitent accéder à ces données. Au lieu d’avoir une seule permission déléguée, concevez vos autorisations avec le principe Confiance Zéro du droit d’accès minimal à l’esprit. Il peut être difficile d’accéder à un modèle à privilèges minimum plus tard si toutes les applications clientes commencent par un accès privilégié complet.

Souvent, les développeurs se trouvent dans un modèle d’utilisation d’une autorisation unique comme « accès en tant qu’utilisateur » ou « emprunt d’identité utilisateur » (qui est une expression courante, bien que techniquement inexacte). Les autorisations uniques comme celles-ci autorisent uniquement l’accès complet et privilégié à votre API.

Déclarez les étendues de privilège minimum afin que vos applications ne soient pas vulnérables à la compromission ou utilisées pour effectuer une tâche que vous n’avez jamais prévue. Définissez vos plusieurs étendues dans les autorisations d’API. Par exemple, séparez les étendues de la lecture et de la mise à jour des données et envisagez d’offrir des autorisations en lecture seule. Un « accès en écriture » inclut des privilèges pour les opérations de création, de mise à jour et de suppression. Un client ne devrait jamais exiger d’accès en écriture seulement pour lire des données.

Lorsque votre API travaille avec des données sensibles, prenez en compte les autorisations d’accès « standard » et « complet ». Limitez les propriétés sensibles afin qu’une autorisation standard n’autorise pas l’accès (par exemple). Resource.Read Implémentez ensuite une autorisation d’accès « complet » (par exemple, Resource.ReadFull) qui renvoie les propriétés et les informations sensibles.

Évaluez toujours les autorisations que vous demandez afin de vous assurer que vous recherchez l'ensemble de privilèges le moins élevé possible pour effectuer le travail. Évitez de demander des autorisations de privilège plus élevées. Au lieu de cela, créez une autorisation individuelle pour chaque scénario principal. Reportez-vous à la référence des autorisations Microsoft Graph pour obtenir de bons exemples de cette approche. Recherchez et utilisez uniquement le bon nombre d’autorisations pour répondre à vos besoins.

Dans le cadre de vos définitions d’étendue, déterminez si la plage d’opérations pouvant être effectuée avec une étendue particulière nécessite le consentement de l’administrateur.

En tant que concepteur d’API, vous pouvez fournir des conseils sur les étendues qui peuvent nécessiter en toute sécurité uniquement le consentement de l’utilisateur. Toutefois, les admins client peuvent configurer un locataire afin que toutes les autorisations nécessitent le consentement administrateur. Si vous définissez une étendue comme nécessitant le consentement de l’administrateur, l’autorisation nécessite toujours le consentement de l’administrateur.

Lorsque vous décidez du consentement de l’utilisateur ou de l’administrateur, vous avez deux considérations principales :

  1. Indique si la plage d’opérations derrière l’autorisation affecte plus d’un seul utilisateur. Si l’autorisation permet à l’utilisateur de choisir l’application qui peut accéder uniquement à ses propres informations, le consentement de l’utilisateur peut être approprié. Par exemple, l’utilisateur peut donner son consentement pour choisir son application préférée pour l’email. Toutefois, si les opérations derrière l’autorisation impliquent plus d’un seul utilisateur (par exemple, l’affichage de profils utilisateur complets d’autres utilisateurs), définissez cette autorisation comme nécessitant le consentement de l’administrateur.

  2. Indique si la plage d’opérations derrière l’autorisation a une étendue. Par exemple, une étendue est lorsqu’une autorisation permet à une application de modifier tout dans un locataire ou de faire quelque chose qui peut être irréversible. Une étendue indique que vous avez besoin du consentement administrateur plutôt que du consentement de l’utilisateur.

Errez du côté conservateur et demandez le consentement de l’administrateur si vous êtes en doute. Décrivez clairement et concis les conséquences du consentement dans vos chaînes d’autorisation. Supposons que la personne qui lit vos chaînes de description n’a aucune connaissance de vos API ou de votre produit.

Évitez d'ajouter vos API aux autorisations existantes d'une manière qui modifie la sémantique de l'autorisation. La surcharge des autorisations existantes dilue le raisonnement sur lequel les clients ont précédemment accordé leur consentement.

Définition des autorisations d'application

Lorsque vous créez des applications non-utilisateur, vous n’avez pas d’utilisateur que vous pouvez demander un nom d’utilisateur et un mot de passe ou une authentification multifacteur (MFA). Si votre API sera appelée par des applications sans utilisateurs (par exemple, des charges de travail, des services et des démons), vous devez définir des autorisations d’application pour votre API. Lorsque vous définissez une autorisation d’application, vous utiliserez un rôle d’application au lieu d’utiliser des étendues.

Comme avec les permissions déléguées, vous fournirez des autorisations d’application granulaires afin que les charges de travail appelant votre API puissent suivre le droit d’accès minimal et s’aligner sur les principes de Confiance Zéro. Évitez de publier un seul rôle d’application (autorisation d’application) et une seule étendue (permission déléguée) ou exposer toutes les opérations à chaque client.

Les charges de travail s’authentifient avec les informations d’identification du client et demandent un jeton à l’aide de l’étendue.default, comme illustré dans l’exemple de code suivant.

// With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the 
// application permissions need to be set statically (in the portal or by PowerShell), 
// and then granted by a tenant administrator
string[] scopes = new string[] { "https://kkaad.onmicrosoft.com/webapi/.default" };
 
AuthenticationResult result = null;
try
{
  result = await app.AcquireTokenForClient(scopes)
    .ExecuteAsync();
  Console.WriteLine("Token acquired \n");
}
catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
{
  // Invalid scope. The scope has to be of the form "https://resourceurl/.default"
  // Mitigation: change the scope to be as expected
  Console.WriteLine("Scope provided is not supported");
}

Les autorisations nécessitent le consentement de l’administrateur lorsqu’il n’existe aucun utilisateur devant l’application et lorsque l’autorisation d’application active un large éventail d’opérations.

Application de l’accès

Assurez-vous que vos API appliquent l’accès en validant et en interprétant les jetons d’accès que l’application appelante fournit en tant que jetons du porteur dans l’en-tête d’autorisation de la requête HTTPS. Vous pouvez appliquer l’accès en validant les jetons, en gérant l’actualisation des métadonnées et en appliquant des étendues et des rôles, comme décrit dans les sections suivantes.

Validation des jetons

Une fois que votre API reçoit un jeton, elle doit valider le jeton. La validation garantit que le jeton provient de l’émetteur approprié comme non modifié et non modifié. Vérifiez la signature, car vous n’obtenez pas le jeton directement à partir de Microsoft Entra ID, comme vous le faites avec les jetons d’ID. Validez la signature une fois que votre API reçoit un jeton d’une source non approuvée sur le réseau.

Étant donné qu’il existe des vulnérabilités connues autour de la vérification de la signature de jeton Web JSON, utilisez une bibliothèque de validation de jeton standard bien gérée et établie. Les bibliothèques d’authentification (telles que Microsoft.Identity.Web ou Passport, si vous créez un nœud) utilisent les étapes appropriées et atténuent les vulnérabilités connues.

Si vous le souhaitez, étendez la validation des jetons. Utilisez la revendication ID de client (tid) pour restreindre les locataires dans lesquels votre API peut obtenir un jeton. Utiliser les revendications azp et appid pour filtrer les applications qui peuvent appeler votre API. Utilisez la revendication ID d’objet (oid) pour affiner davantage l’accès à des utilisateurs individuels.

Gestion de l’actualisation des métadonnées

Veillez toujours à ce que votre bibliothèque de validation de jeton gère efficacement les métadonnées requises. Dans ce cas, les métadonnées sont les clés publiques, la paire de clés privées que Microsoft utilise pour signer des jetons Microsoft Entra. Lorsque vos bibliothèques valident ces jetons, ils obtiennent notre liste publiée de clés de signature publiques à partir d’une adresse Internet connue. Assurez-vous que l’environnement d’hébergement a le bon minutage pour obtenir ces clés.

Par exemple, les bibliothèques plus anciennes étaient parfois codées en dur pour mettre à jour ces clés de signature publiques toutes les 24 heures. Envisagez quand Microsoft Entra ID doit faire pivoter rapidement ces clés et les clés que vous avez téléchargées n’ont pas inclus les nouvelles clés pivotées. Votre API peut être hors connexion pendant un jour pendant qu’elle attend son cycle d’actualisation des métadonnées. Référencez des conseils d’actualisation des métadonnées spécifiques pour vous assurer que vous obtenez correctement les métadonnées. Si vous utilisez une bibliothèque, assurez-vous qu’elle traite ces métadonnées dans un délai raisonnable.

Application des étendues et des rôles

Après avoir validé votre jeton, votre API examine les revendications du jeton pour déterminer son fonctionnement.

Pour les jetons de permission déléguée, votre API inspecte la revendication d’étendue (scp) pour voir ce que l’application a le consentement à faire. Inspectez les revendications de l’ID d’objet (oid) ou de la clé d’objet (sub) pour voir l’utilisateur au nom duquel l’application fonctionne.

Votre API case activée ensuite pour vous assurer que l’utilisateur a également accès à l’opération demandée. Si votre API a défini des rôles pour l’attribution d’utilisateurs et de groupes, avez votre API case activée pour toutes les revendications de rôles dans le jeton et se comportent en conséquence. Pour les jetons d’autorisation d’application, il n’y aura aucune revendication d’étendue (scp). Au lieu de cela, votre API détermine les autorisations d’application reçues par la charge de travail en inspectant la revendication des rôles.

Une fois que votre API a validé le jeton et les étendues et traité l’ID d’objet (oid), la clé d’objet (sub) et les revendications de rôles, votre API peut retourner les résultats.

Étapes suivantes