Application web qui appelle des API web : Configuration de code

Comme illustré dans le scénario Application web qui connecte des utilisateurs, l'application web utilise le flux du code d'autorisation OAuth 2.0 pour connecter l'utilisateur. Ce flux comporte deux étapes :

  1. Demande d’un code d’autorisation. Cette partie délègue à la plateforme d'identités Microsoft un dialogue privé avec l'utilisateur. Pendant ce dialogue, l'utilisateur se connecte et consent à utiliser des API web. Lorsque le dialogue privé se termine correctement, l'application web reçoit un code d'autorisation sur son URI de redirection.
  2. Demande d’un jeton d’accès pour l’API en échange du code d’autorisation.

Les scénarios Application web qui connecte des utilisateurs ne couvraient que la première étape. Vous allez ici apprendre à modifier votre application web afin qu'elle appelle les API web en plus de connecter les utilisateurs.

Bibliothèques Microsoft prenant en charge les applications web

Les bibliothèques Microsoft suivantes prennent en charge les applications web :

Langage/framework Projet sur
GitHub
Package Bien démarrer
démarré
Connexion des utilisateurs Accès aux API web Disponibilité générale ou
Préversion publique1
.NET MSAL.NET Microsoft.Identity.Client La bibliothèque ne peut pas demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA
.NET Microsoft.IdentityModel Microsoft.IdentityModel Library cannot request ID tokens for user sign-in.2 Library cannot request access tokens for protected web APIs.2 GA
ASP.NET Core ASP.NET Core Microsoft.AspNetCore.Authentication Démarrage rapide La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque ne peut pas demander des jetons d’accès pour les API web protégées. GA
ASP.NET Core Microsoft.Identity.Web Microsoft.Identity.Web Démarrage rapide La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA
Java MSAL4J msal4j Démarrage rapide La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA
Spring spring-cloud-azure-starter-active-directory spring-cloud-azure-starter-active-directory Didacticiel La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA
Node.js MSAL Node msal-node Démarrage rapide La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA
Python MSAL Python msal Démarrage rapide La bibliothèque peut demander des jetons d’ID pour la connexion de l’utilisateur. La bibliothèque peut demander des jetons d’accès pour les API web protégées. GA

1Les conditions d’utilisation supplémentaires des préversions Microsoft Azure s’appliquent aux bibliothèques en préversion publique.

2 La bibliothèque Microsoft.IdentityModelvalide uniquement les jetons. Elle ne peut pas demander de jetons d’ID ni de jetons d’accès.

Sélectionnez l'onglet correspondant à la plateforme qui vous intéresse :

Secrets clients ou certificats clients

Dans la mesure où votre application web appelle désormais une API web en aval, fournissez un secret client ou un certificat client dans le fichier appsettings.json. Vous pouvez également ajouter une section spécifiant ce qui suit :

  • URL de l’API web en aval ;
  • étendues requises pour appeler l’API.

Dans l’exemple suivant, la section GraphBeta spécifie ces paramètres.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "[Client_id-of-web-app-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",
    "TenantId": "common",

   // To call an API
   "ClientSecret": "[Copy the client secret added to the app from the Azure portal]",
   "ClientCertificates": [
  ]
 },
 "GraphBeta": {
    "BaseUrl": "https://graph.microsoft.com/beta",
    "Scopes": "user.read"
    }
}

À la place d’un secret client, vous pouvez fournir un certificat client. L’extrait de code suivant montre l’utilisation d’un certificat stocké dans Azure Key Vault.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "[Client_id-of-web-app-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",
    "TenantId": "common",

   // To call an API
   "ClientCertificates": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
        "KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
      }
   ]
  },
  "GraphBeta": {
    "BaseUrl": "https://graph.microsoft.com/beta",
    "Scopes": "user.read"
  }
}

Microsoft.Identity.Web offre plusieurs façons de décrire les certificats, que ce soit en définissant une configuration ou en écrivant du code. Pour plus d’informations, consultez Microsoft.Identity.Web - Using certificates sur GitHub.

Startup.cs

Votre application web doit acquérir un jeton pour l’API en aval. Vous le spécifiez en ajoutant la ligne .EnableTokenAcquisitionToCallDownstreamApi() après .AddMicrosoftIdentityWebApp(Configuration). Cette ligne expose le service ITokenAcquisition que vous pouvez utiliser dans vos actions de contrôleur et de page. Toutefois, comme vous le verrez dans les deux options suivantes, il existe un moyen plus simple. Vous devez également choisir une implémentation de cache de jeton, par exemple .AddInMemoryTokenCaches(), dans Startup.cs :

using Microsoft.Identity.Web;

public class Startup
{
  // ...
  public void ConfigureServices(IServiceCollection services)
  {
  // ...
  services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
          .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
            .AddInMemoryTokenCaches();
   // ...
  }
  // ...
}

Les étendues transmises à EnableTokenAcquisitionToCallDownstreamApi sont facultatives et permettent à votre application web de demander les étendues et le consentement de l’utilisateur à ces étendues lors de la connexion. Si vous ne spécifiez pas les étendues, Microsoft.Identity.Web permettra une expérience de consentement incrémentielle.

Si vous ne souhaitez pas acquérir le jeton vous-même, Microsoft.Identity.Web fournit deux mécanismes pour appeler une API web à partir d’une application web. L’option que vous choisissez varie selon que vous souhaitez appeler Microsoft Graph ou une autre API.

Option 1 : Appeler Microsoft Graph

Si vous souhaitez appeler Microsoft Graph, Microsoft.Identity.Web vous permet d’utiliser directement le GraphServiceClient (exposé par le Kit de développement logiciel (SDK) Microsoft Graph) dans vos actions d’API. Pour exposer Microsoft Graph :

  1. Ajoutez le package NuGet Microsoft.Identity.Web. MicrosoftGraph à votre projet.

  2. Ajoutez .AddMicrosoftGraph() après .EnableTokenAcquisitionToCallDownstreamApi() dans le fichier Startup.cs. .AddMicrosoftGraph() a plusieurs remplacements. En utilisant le remplacement qui prend une section de configuration en tant que paramètre, le code devient :

    using Microsoft.Identity.Web;
    
    public class Startup
    {
      // ...
      public void ConfigureServices(IServiceCollection services)
      {
      // ...
      services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
              .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
                .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
                   .AddMicrosoftGraph(Configuration.GetSection("GraphBeta"))
                .AddInMemoryTokenCaches();
       // ...
      }
      // ...
    }
    

Option n°2 : Appeler une API web en aval autre que Microsoft Graph

Pour appeler une API web autre que Microsoft Graph, Microsoft.Identity.Web fournit .AddDownstreamWebApi(), qui demande des jetons et appelle l’API web en aval.

using Microsoft.Identity.Web;

public class Startup
{
  // ...
  public void ConfigureServices(IServiceCollection services)
  {
  // ...
  services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
          .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
               .AddDownstreamWebApi("MyApi", Configuration.GetSection("GraphBeta"))
            .AddInMemoryTokenCaches();
   // ...
  }
  // ...
}

Résumé

Comme avec des API web, vous pouvez choisir diverses implémentations de cache de jeton. Pour plus d’informations, consultez Microsoft.Identity.Web - Token cache serialization sur GitHub.

L’illustration suivante montre les différentes possibilités de Microsoft.Identity.Web et leur impact sur le fichier Startup.cs :

Diagramme de bloc montrant des options de configuration de service dans le point de départ CS pour appeler une API web et spécifier une implémentation de cache de jeton

Notes

Pour bien comprendre les exemples de code présentés ici, vous devez maîtriser les notions de base d'ASP.NET Core, en particulier l'injection de dépendances et le modèle options.

Code qui échange le code d’autorisation

Microsoft.Identity.Web simplifie votre code en définissant les paramètres corrects d’OpenID Connect, en s’abonnant à l’événement code reçu et en échangeant le code. Aucun code supplémentaire n'est nécessaire pour accepter le code d'autorisation. Pour plus d’informations sur le fonctionnement, consultez Code source de Microsoft.Identity.Web.

Au lieu d'utiliser un secret client, l'application cliente confidentielle peut également prouver son identité à l'aide d'un certificat client ou d'une assertion de client. L'utilisation d'assertions de client est un scénario avancé décrit en détail dans Assertions de client.

Cache de jeton

Important

L'implémentation du cache de jetons des applications ou API web est différente de l'implémentation relative aux applications de bureau, qui est souvent basée sur des fichiers. En termes de sécurité et de performances, pour les applications et API web, vous devez impérativement disposer d'un cache de jetons par compte d'utilisateur. Vous devez sérialiser le cache de jetons pour chaque compte.

Le tutoriel ASP.NET Core utilise l’injection de dépendances pour vous laisser déterminer l’implémentation du cache de jetons dans le fichier Startup.cs de votre application. Microsoft.Identity.Web est fourni avec des sérialiseurs de cache de jetons prédéfinis décrits dans Sérialisation du cache de jetons. Une possibilité intéressante consiste à choisir des caches en mémoire distribuée ASP.NET Core :

// Use a distributed token cache by adding:
    services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(
                initialScopes: new string[] { "user.read" })
            .AddDistributedTokenCaches();

// Then, choose your implementation.
// For instance, the distributed in-memory cache (not cleared when you stop the app):
services.AddDistributedMemoryCache();

// Or a Redis cache:
services.AddStackExchangeRedisCache(options =>
{
 options.Configuration = "localhost";
 options.InstanceName = "SampleInstance";
});

// Or even a SQL Server token cache:
services.AddDistributedSqlServerCache(options =>
{
 options.ConnectionString = _config["DistCache_ConnectionString"];
 options.SchemaName = "dbo";
 options.TableName = "TestCache";
});

Pour plus d'informations sur les fournisseurs de cache de jetons, consultez également l'article relatif à la sérialisation du cache de jetons de Microsoft.Identity.Web et la phase Tutoriel sur les applications web ASP.NET Core | Caches de jetons du tutoriel consacré aux applications web.

Étapes suivantes

À ce stade, lorsque l'utilisateur se connecte, un jeton est stocké dans le cache de jetons. Nous allons voir comment il est ensuite utilisé dans d'autres parties de l'application web.

Supprimer les comptes du cache lors de la déconnexion globale