Activation de l’authentification dans une API web avec Azure AD B2C

Pour autoriser l’accès à une API web, vous pouvez traiter uniquement les requêtes incluant un jeton d’accès valide émis par Azure AD B2C (Azure Active Directory B2C). Cet article explique comment activer l’autorisation Azure AD B2C sur une API web. Une fois que vous aurez suivi la procédure de cet article, seuls les utilisateurs qui auront obtenu un jeton d’accès valide sont autorisés à appeler vos points de terminaison d’API web.

Configuration requise

Avant de commencer, lisez l’un des articles suivants, qui expliquent comment configurer l’authentification pour les applications qui appellent des API web. Ensuite, suivez la procédure de cet article pour remplacer l’exemple d’API web par la vôtre.

Vue d’ensemble

L’authentification par jeton garantit que les requêtes adressées à une API web incluent un jeton d’accès valide.

L’application effectue les étapes suivantes :

  1. Elle authentifie les utilisateurs auprès d’Azure AD B2C.

  2. Elle obtient un jeton d’accès doté des autorisations requises (étendues) pour le point de terminaison de l’API web.

  3. Elle transmet le jeton d’accès comme jeton du porteur dans l’en-tête d’authentification de la requête HTTP au format suivant :

    Authorization: Bearer <access token>
    

L’API web suit les étapes suivantes :

  1. Elle lit le jeton du porteur à partir de l’en-tête d’authentification dans la requête HTTP.

  2. Elle valide le jeton.

  3. Elle valide les autorisations (étendues) dans le jeton.

  4. Elle lit les revendications encodées dans le jeton (facultatif).

  5. Elle répond à la requête HTTP.

Vue d’ensemble de l’inscription de l’application

Pour permettre à votre application de se connecter avec Azure AD B2C et d’appeler une API web, vous devez inscrire deux applications dans l’annuaire Azure AD B2C.

  • L’inscription de l’application web, mobile ou SPA permet à votre application de se connecter avec Azure AD B2C. Ce processus génère un ID d’application, également appelé ID client, qui sert d’identificateur unique de l’application (par exemple ID d’application : 1).

  • L’inscription de l’API web permet à votre application d’appeler une API web protégée. Elle expose les autorisations de l’API web (étendues). Ce processus génère un ID d’application, qui sert d’identificateur unique de l’API web (par exemple ID d’application : 2). Accordez à votre application (ID d’application : 1) des autorisations sur les étendues de l’API web (ID d’application : 2).

Les inscriptions et l’architecture des applications sont décrites dans le diagramme suivant :

Diagram of the application registrations and the application architecture for an app with web API.

Préparer votre environnement de développement

Dans les sections suivantes, vous créez un projet d’API web. Sélectionnez votre langage de programmation : ASP.NET Core ou Node.js. Vérifiez que votre ordinateur exécute l’un des logiciels suivants :

Étape 1 : Créer une API web protégée

Créez un projet d’API web. Tout d’abord, sélectionnez le langage de programmation que vous souhaitez utiliser : ASP.NET Core ou Node.js.

Utilisez la commande dotnet new. La commande dotnet new crée un dossier nommé TodoList comportant les ressources du projet d’API web. Ouvrez le répertoire, puis Visual Studio Code.

dotnet new webapi -o TodoList
cd TodoList
code . 

Lorsqu’il vous est demandé d’« ajouter les ressources requises au projet », sélectionnez Oui.

Étape 2 : Installer les dépendances

Ajoutez la bibliothèque d’authentification à votre projet d’API web. Elle analyse l’en-tête d’authentification HTTP, valide le jeton et extrait les revendications. Pour plus d’informations, consultez la documentation de la bibliothèque.

Pour ajouter la bibliothèque d’authentification, installez le package en exécutant la commande suivante :

dotnet add package Microsoft.Identity.Web

Étape 3 : Lancer la bibliothèque d’authentification

Ajoutez le code nécessaire pour lancer la bibliothèque d’authentification.

Ouvrez Startup.cs, puis ajoutez les déclarations using suivantes au début de la classe :

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

Recherchez la fonction ConfigureServices(IServiceCollection services). Ensuite, ajoutez l’extrait de code suivant avant la ligne de code services.AddControllers(); :

public void ConfigureServices(IServiceCollection services)
{
    // Adds Microsoft Identity platform (Azure AD B2C) support to protect this Api
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(options =>
    {
        Configuration.Bind("AzureAdB2C", options);

        options.TokenValidationParameters.NameClaimType = "name";
    },
    options => { Configuration.Bind("AzureAdB2C", options); });
    // End of the Microsoft Identity platform block    

    services.AddControllers();
}

Recherchez la fonction Configure. Ensuite, ajoutez l’extrait de code suivant juste après la ligne de code app.UseRouting(); :

app.UseAuthentication();

Après modification, votre code se présente ainsi :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();
    
    // Add the following line 
    app.UseAuthentication();
    // End of the block you add
    
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Étape 4 : Ajouter les points de terminaison

Ajoutez deux points de terminaison à votre API web :

  • Point de terminaison /public anonyme : il retourne la date et l’heure actuelles. Utilisez-le pour déboguer votre API web avec des appels anonymes.
  • Point de terminaison /hello protégé : il retourne la valeur de la revendication name dans le jeton d’accès.

Ajout du point de terminaison anonyme

Dans le dossier /Controllers, ajoutez un fichier PublicController.cs, puis ajoutez-le à l’extrait de code suivant :

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace TodoList.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class PublicController : ControllerBase
    {
        private readonly ILogger<PublicController> _logger;

        public PublicController(ILogger<PublicController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public ActionResult Get()
        {
            return Ok( new {date = DateTime.UtcNow.ToString()});
        }
    }
}

Ajout du point de terminaison protégé

Dans le dossier /Controllers, ajoutez un fichier HelloController.cs, puis ajoutez-le à l’extrait de code suivant :

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Web.Resource;

namespace TodoList.Controllers
{
    [Authorize]
    [RequiredScope("tasks.read")]
    [ApiController]
    [Route("[controller]")]
    public class HelloController : ControllerBase
    {

        private readonly ILogger<HelloController> _logger;
        private readonly IHttpContextAccessor _contextAccessor;

        public HelloController(ILogger<HelloController> logger, IHttpContextAccessor contextAccessor)
        {
            _logger = logger;
            _contextAccessor = contextAccessor;
        }

        [HttpGet]
        public ActionResult Get()
        {
            return Ok( new { name = User.Identity.Name});
        }
    }
}

Le contrôleur HelloController est doté de l’attribut AuthorizeAttribute, qui limite l’accès aux utilisateurs authentifiés uniquement.

Le contrôleur comprend également [RequiredScope("tasks.read")]. RequiredScopeAttribute vérifie que l’API web est appelée avec les bonnes étendues, tasks.read.

Étape 5 : Configurer le serveur web

Dans un environnement de développement, définissez l’API web de sorte qu’elle écoute sur le numéro de port des requêtes HTTP ou HTTPS entrantes. Dans cet exemple, utilisez le port HTTP 6000 et le port HTTPS 6001. L’URI de base de l’API web est http://localhost:6000 pour HTTP et https://localhost:6001 pour HTTPS.

Ajoutez l’extrait de code JSON suivant au fichier appsettings.json.

"Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://localhost:6000"
      },
      "Https": {
         "Url": "https://localhost:6001"   
        }
    }
  }

Étape 6 : Configurer l’API web

Ajoutez des configurations à un fichier de configuration. Ce fichier contient des informations sur votre fournisseur d’identité Azure AD B2C. L’application API web les utilise pour valider le jeton d’accès transmis comme jeton du porteur par l’application web.

Dans le dossier racine du projet, ouvrez le fichier appsettings.json, puis ajoutez les paramètres suivants :

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-api-app-application-id>",
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  // More settings here
}

Dans le fichier appsettings.json, mettez à jour les propriétés suivantes :

Section Clé Valeur
AzureAdB2C Instance La première partie du nom de locataire Azure AD B2C (par exemple https://contoso.b2clogin.com).
AzureAdB2C Domain Nom du locataire complet Azure AD B2C (par exemple contoso.onmicrosoft.com).
AzureAdB2C ClientId ID de l’application API web. Dans le diagramme précédent, il s’agit de l’application ID d’application : 2. Pour savoir comment obtenir l’ID d’inscription de votre application API web, consultez Prérequis.
AzureAdB2C SignUpSignInPolicyId Flux d’utilisateurs ou stratégie personnalisée. Pour savoir comment obtenir votre flux d’utilisateurs ou votre stratégie, consultez Prérequis.

Étape 7 : Exécuter et tester l’API web

Enfin, exécutez l’API web avec vos paramètres d’environnement Azure AD B2C.

Dans l’interface de commande, lancez l’application web en exécutant la commande suivante :

 dotnet run

La sortie suivante s’affiche, ce qui signifie que votre application est opérationnelle et prête à recevoir des demandes.

Now listening on: http://localhost:6000

Pour arrêter le programme, sélectionnez Ctrl+C dans l’interface de commande. Vous pouvez réexécuter l’application avec la commande node app.js.

Conseil

Pour exécuter la commande dotnet run, vous pouvez également utiliser le débogueur Visual Studio Code. Ce débogueur intégré permet d’accélérer la boucle de modification, de compilation et de débogage.

Ouvrez un navigateur et accédez à http://localhost:6000/public. Dans la fenêtre du navigateur, le texte suivant s’affiche, ainsi que la date et l’heure actuelles.

Étape 8 : Appeler l’API web à partir de l’application

Essayez d’appeler le point de terminaison d’API web protégé sans jeton d’accès. Ouvrez un navigateur et accédez à http://localhost:6000/hello. L’API web renvoie un message d’erreur HTTP non autorisé, ce qui confirme qu’elle est bien protégée par un jeton de porteur.

Continuez à configurer votre application pour appeler l’API web. Pour plus d’informations, consultez la section Prérequis.

Regardez cette vidéo pour en savoir plus sur certaines des meilleures pratiques à connaître lorsque vous intégrez Azure AD B2C avec une API.

Étapes suivantes

Retrouvez l’exemple complet sur GitHub :