Démarrage rapide : Protéger une API web ASP.NET Core

Dans ce guide de démarrage rapide, vous protégez une API web ASP.NET Core avec Microsoft Entra ID à l’aide de Microsoft. Identity.Web. Vous ajoutez un intergiciel d’authentification qui valide les jetons du porteur et limite l’accès aux appelants autorisés.

Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.

Prerequisites

Option 1 : Créer à partir d’un modèle (le plus rapide)

Utilisez le modèle ASP.NET Core avec l’authentification intégrée Microsoft Entra pour générer une structure d’un projet d’API protégé.

1. Créer le projet

Exécutez les commandes suivantes pour créer un projet d’API web avec l’authentification à organisation unique et accédez au répertoire du projet :

dotnet new webapi --auth SingleOrg --name MyWebApi
cd MyWebApi

2. Configurer l’inscription d’application

Remplacez les valeurs d’espace réservé dans appsettings.json par les détails de l’inscription de votre application Microsoft Entra :

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  }
}

3. Exécuter l’API

Démarrez l’application :

dotnet run

Votre API est désormais protégée à l’adresse https://localhost:5001.

Terminé ! Les demandes nécessitent désormais un jeton d’accès valide.


Option 2 : Ajouter à l’API web existante

Si vous disposez déjà d’une API web ASP.NET Core, ajoutez Microsoft Entra authentification en procédant comme suit.

1. Installer le package NuGet

Ajoutez le package NuGet Microsoft.Identity.Web à votre projet :

dotnet add package Microsoft.Identity.Web

2. Configurer l’authentification dans Program.cs

Inscrivez les services d’authentification et d’autorisation dans le pipeline de démarrage de votre application. Le code suivant configure l’authentification du porteur JWT avec Microsoft Entra validation :

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");

// Add authorization
builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication(); //  Add authentication middleware
app.UseAuthorization();

app.MapControllers();

app.Run();

3. Ajouter une configuration à appsettings.json

Ajoutez la section de configuration Microsoft Entra avec les détails de votre locataire et de votre application. Définissez le niveau de journalisation pour Microsoft.Identity.Web sur Information pour résoudre les problèmes de validation des jetons :

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "Information"
    }
  }
}

4. Protéger vos points de terminaison d’API

Appliquez l’attribut [Authorize] aux contrôleurs ou aux actions qui nécessitent un jeton d’accès valide.

Exiger l’authentification pour tous les points de terminaison :

Le contrôleur suivant nécessite un jeton d’accès valide pour toutes les actions et montre comment accéder aux revendications utilisateur :

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Authorize] //  Require valid access token
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        // Access user information
        var userId = User.FindFirst("oid")?.Value;
        var userName = User.Identity?.Name;

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Protected data"
        });
    }
}

Exiger des portées spécifiques :

Utilisez l’attribut [RequiredScope] pour appliquer des autorisations affinées sur des actions individuelles :

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TodoController : ControllerBase
{
    [HttpGet]
    [RequiredScope("access_as_user")] //  Require specific scope
    public IActionResult GetAll()
    {
        return Ok(new[] { "Todo 1", "Todo 2" });
    }

    [HttpPost]
    [RequiredScope("write")] //  Different scope for write operations
    public IActionResult Create([FromBody] string item)
    {
        return Created("", item);
    }
}

5. Exécuter et tester

Démarrez l’application et vérifiez que les demandes non authentifiées sont rejetées :

dotnet run

Testez avec un outil tel que Postman ou CURL. Une requête non authentifiée retourne 401 Unauthorized:

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://localhost:5001/api/weatherforecast

Succès ! Votre API valide désormais les bearer tokens.


Configuration de l’inscription des applications

Avant que votre API puisse valider les jetons, vous avez besoin d’une inscription d’application Microsoft Entra. Suivez ces étapes dans le portail Azure.

1. Inscrire votre API

  1. Connectez-vous au portail Azure
  2. Accédez à Microsoft Entra ID>inscriptions d'applications>New registration
  3. Entrez un nom (par exemple, « Mon API web »)
  4. Sélectionner un seul locataire (le plus courant pour les API)
  5. Aucun URI de redirection nécessaire pour les API
  6. Cliquez sur Inscrire

2. Exposer une étendue d’API

Définissez les autorisations (étendues) que les applications clientes peuvent demander lors de l’appel de votre API.

  1. Dans l’inscription de votre application API, accédez à Exposer une API
  2. Cliquez sur Ajouter une étendue
  3. Acceptez l’URI d’ID d’application par défaut ou personnalisez-le (par exemple, api://your-api-client-id)
  4. Ajoutez une étendue :
    • Nom de l’étendue :access_as_user
    • Qui peut donner son consentement : Administrateurs et utilisateurs
    • Nom d’affichage du consentement administrateur : « Accéder à mon API web »
    • Description du consentement de l’administrateur : « Permet à l’application d’accéder à l’API web pour le compte de l’utilisateur connecté »
  5. Cliquez sur Ajouter une étendue

3. Notez l’ID d’application

Copiez l’ID d’application (client) à partir de la page vue d’ensemble de l’inscription de l’application. Cette valeur est votre ClientId en appsettings.json.


Créer une inscription d’application cliente (pour les tests)

Pour tester votre API protégée, inscrivez une application cliente distincte qui acquiert des jetons et appelle l’API.

1. Inscrire une application cliente

  1. Dans Microsoft Entra ID>inscriptions d'applications, créez une autre inscription
  2. Nommez-le (par exemple, « Mon client API »)
  3. Sélectionner des types de comptes
  4. Ajouter l’URI de redirection : https://localhost:7000/signin-oidc (s’il s’agit d’une application web)
  5. Cliquez sur Inscrire

2. Accorder des autorisations d’API

Accordez à l’application cliente l’autorisation d’appeler votre API avec les étendues que vous avez définies.

  1. Dans l’inscription de l’application cliente, accédez aux autorisations d’API
  2. Cliquez sur Ajouter une autorisation>Mes API
  3. Sélectionnez votre enregistrement d'API
  4. Vérifiez l’étendue access_as_user.
  5. Cliquez sur Ajouter des autorisations
  6. Cliquez sur Accorder le consentement de l’administrateur (si nécessaire)

3. Créer un secret client (avec des clients confidentiels)

Si votre application cliente s’exécute sur un serveur (pas un navigateur ou un appareil mobile), créez une clé secrète client pour l’authentification.

  1. Accédez à Certificats et secrets
  2. Cliquez sur Nouvelle clé secrète client
  3. Ajouter une description et une expiration
  4. Cliquez sur Ajouter
  5. Copiez immédiatement la valeur du secret : vous ne pourrez pas la voir à nouveau

Tester votre API protégée

Vérifiez que votre API valide correctement les jetons en envoyant des demandes authentifiées.

Utilisation de Postman

Configurez l’authentification OAuth 2.0 dans Postman pour acquérir un jeton et appeler votre API.

  1. Créer une demande dans Postman
  2. Configurez l’authentification OAuth 2.0 :
    • Type d’octroi : Code d’autorisation (pour le contexte utilisateur) ou Informations d’identification du client (pour le contexte de l’application)
    • URL d’authentification :https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • URL du jeton d’accès :https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • ID client : ID client de votre application cliente
    • Clé secrète client : Secret de votre application cliente
    • Portée:api://your-api-client-id/access_as_user
  3. Cliquez sur Obtenir un nouveau jeton d’accès
  4. Utiliser le jeton pour appeler votre API

Utilisation du code (exemple C#)

L’exemple suivant utilise MSAL.NET pour acquérir un jeton avec le flux d’informations d’identification du client et appeler l’API protégée :

// In a console app or client application
using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("client-app-id")
    .WithClientSecret("client-secret")
    .WithAuthority("https://login.microsoftonline.com/{tenant-id}")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://your-api-client-id/.default" }
).ExecuteAsync();

var accessToken = result.AccessToken;

// Use the token to call your API
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://localhost:5001/api/weatherforecast");

Options de configuration courantes

Microsoft. Identity.Web prend en charge plusieurs modèles de configuration pour différents scénarios.

Exiger des étendues spécifiques dans la configuration

Au lieu d’utiliser l’attribut [RequiredScope] , vous pouvez configurer les étendues requises globalement dans appsettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id",
    "Scopes": "access_as_user"
  }
}

Accepter des jetons de plusieurs locataires

Pour accepter des jetons de n’importe quel client Microsoft Entra, définissez TenantId sur common :

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "ClientId": "your-api-client-id"
  }
}

Configurer la validation des jetons

Si votre API appelle des API en aval (telles que Microsoft Graph), activez l’acquisition de jetons et configurez un cache de jetons :

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi() // If your API calls other APIs
    .AddInMemoryTokenCaches();

Étapes suivantes

Maintenant que vous disposez d’une API protégée, explorez ces rubriques :

Résolution des problèmes

401 Non autorisé

Problème: L’API retourne 401 même avec un jeton.

Causes possibles :

  • L’audience de jeton (aud déclaration) ne correspond pas à celle de votre API ClientId
  • Le jeton a expiré
  • Le jeton est pour le locataire incorrect
  • L’étendue requise est manquante

Solution: Décodez le jeton à jwt.ms et vérifiez les revendications. Consultez journalisation et diagnostics pour obtenir une résolution des problèmes détaillée.

AADSTS50013 : signature non valide

Problème: La validation de la signature de jeton échoue.

Solution: Assurez-vous que votre TenantId et ClientId êtes correct. Le jeton doit être émis par l’autorité attendue. Activez la journalisation détaillée pour afficher les erreurs de validation.

Étendues introuvables dans le jeton

Problème:[RequiredScope] l’attribut échoue.

Solution:

  1. Vérifiez que l'application cliente est autorisée pour le périmètre
  2. Vérifiez que le consentement de l’administrateur a été accordé (si nécessaire)
  3. Consultez le Guide d’autorisation pour connaître les modèles de validation d’étendue complets
  4. Vérifiez que le périmètre est demandé lors de l’acquisition du jeton (par exemple, api://your-api/.default ou des périmètres spécifiques)

Voir plus :Guide de résolution des problèmes liés à l’API web