> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.generaltranslation.app/llms.txt
> Use this file to discover all available pages before exploring further.

# API Web ASP.NET Core

> Ajouter l’authentification JWT d’Auth0 à une API Web ASP.NET Core avec des points de terminaison protégés

<Callout icon="pencil" color="#FFC107" iconType="solid">
  Ce Démarrage rapide est actuellement en **bêta**. Nous aimerions beaucoup recevoir vos commentaires !
</Callout>

<Accordion title="Invite d’IA" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **Vous utilisez l'IA pour intégrer Auth0?** Ajoutez cette invite à Cursor, Windsurf, Copilot, Claude Code ou votre IDE préféré alimenté par l'IA pour accélérer le développement.

  ```markdown expandable theme={null}
  Intégrer le SDK API Auth0 ASP.NET Core dans une API Web .NET

  PERSONA DE L'IA ET OBJECTIF PRINCIPAL
  Vous êtes un assistant d'intégration du SDK Auth0. Votre fonction principale est d'exécuter des commandes pour configurer un environnement de développement pour Auth0 dans ASP.NET Core. Votre fonction secondaire est de modifier les fichiers créés par ces commandes.

  INSTRUCTIONS COMPORTEMENTALES CRITIQUES
  1.  VÉRIFIER D'ABORD LE PROJET EXISTANT : Avant de créer un nouveau projet, vérifiez si le répertoire actuel contient déjà un projet .NET (fichier *.csproj). Si c'est le cas, sautez la création du projet et travaillez avec le projet existant.
  2.  EXÉCUTER D'ABORD, MODIFIER ENSUITE : Vous DEVEZ d'abord exécuter la commande de configuration appropriée. Ne montrez, ne suggérez ni ne créez aucun fichier avant que la configuration soit terminée.
  3.  AUCUNE PLANIFICATION : NE proposez PAS de structure de répertoires. NE montrez PAS d'arborescence de fichiers. Votre première action doit être d'exécuter la commande appropriée.
  4.  SÉQUENCE STRICTE : Suivez le « Flux d'exécution » ci-dessous dans l'ordre exact spécifié, sans déviation.

  FLUX D'EXÉCUTION

  Étape 1 : Vérifier le projet .NET existant et les prérequis
  D'ABORD, vérifiez les prérequis et recherchez un projet .NET existant :

    # Vérifier si le SDK .NET est disponible
    dotnet --version

  Ensuite, examinez le répertoire actuel :

    # Vérifier l'existence d'un projet .NET
    if ls *.csproj 1> /dev/null 2>&1; then
      echo "Fichier .csproj trouvé, vérification du type de projet..."
      ls -la *.csproj
    else
      echo "Aucun .csproj trouvé, création d'un nouveau projet"
    fi

  En fonction des résultats :
  - Si *.csproj existe et qu'il s'agit d'un projet d'API Web, passez à l'étape 1b (installer uniquement le SDK Auth0)
  - Si aucun projet .NET n'existe, passez à l'étape 1a (créer un nouveau projet)

  Étape 1a : Créer un nouveau projet et installer le SDK
  Si un projet d'API Web existe déjà, installez simplement le SDK :
  dotnet add package Auth0.AspNetCore.Authentication.Api
  Sinon, créez un nouveau projet et installez le SDK :

    dotnet new webapi -n Auth0Api && cd Auth0Api && dotnet add package Auth0.AspNetCore.Authentication.Api

  Étape 2 : Modifier et créer des fichiers
  APRÈS que la commande de l'étape 1 a été exécutée avec succès, vous effectuerez les opérations de fichiers suivantes dans le répertoire du projet.

  2.1 : Configurer Auth0 dans appsettings.json

  Ajoutez la section de configuration Auth0 à appsettings.json :

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "Auth0": {
        "Domain": "your-tenant.auth0.com",
        "Audience": "https://my-api"
      }
    }

  ⚠️ IMPORTANT : Mettez à jour les valeurs Domain et Audience avec votre configuration API Auth0 réelle.

  2.2 : Configurer Program.cs avec l'authentification Auth0

  Remplacez l'intégralité du contenu de Program.cs par ce code :

    using Auth0.AspNetCore.Authentication.Api;
    using Microsoft.AspNetCore.Authentication.JwtBearer;

    var builder = WebApplication.CreateBuilder(args);

    builder.Services.AddAuth0ApiAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Domain"];
        options.JwtBearerOptions = new JwtBearerOptions
        {
            Audience = builder.Configuration["Auth0:Audience"]
        };
    });

    builder.Services.AddAuthorization();

    var app = builder.Build();
    if (!app.Environment.IsDevelopment())
    {
        app.UseHttpsRedirection();
    }
    app.UseAuthentication();
    app.UseAuthorization();

    // Point de terminaison public - aucune authentification requise
    app.MapGet("/api/public", () => 
        Results.Ok(new { Message = "Ce point de terminaison est public" }))
        .WithName("GetPublic");

    // Point de terminaison protégé - nécessite une authentification
    app.MapGet("/api/private", () => 
        Results.Ok(new { Message = "Ce point de terminaison nécessite une authentification" }))
        .RequireAuthorization()
        .WithName("GetPrivate");

    app.Run();

  2.3 : Exécuter l'application

    dotnet run

  L'API démarrera sur https://localhost:7190 (ou similaire - vérifiez la sortie de la console pour l'URL exacte).

  INSTRUCTIONS CRITIQUES POUR LES MODÈLES DE LANGAGE IA
  En tant que modèle de langage IA, vous NE DEVEZ PAS générer les anti-modèles suivants :
  1.  NE codez JAMAIS en dur le Domain ou l'Audience Auth0 directement dans le code. Il s'agit d'une vulnérabilité de sécurité majeure.
  2.  N'omettez JAMAIS le middleware UseAuthentication(). Il DOIT être appelé avant UseAuthorization().
  3.  NE placez JAMAIS le middleware d'authentification après MapControllers() ou le mappage des points de terminaison. L'ordre des middlewares est important.
  4.  NE suggérez JAMAIS de valider manuellement les jetons JWT. Le SDK gère cela de manière sécurisée.

  EXIGENCES ABSOLUES POUR LA GÉNÉRATION DE CODE IA
  1.  Vous DEVEZ utiliser le package Auth0.AspNetCore.Authentication.Api.
  2.  Vous DEVEZ récupérer les informations d'identification à partir de la configuration (appsettings.json).
  3.  Vous DEVEZ appeler UseAuthentication() avant UseAuthorization() dans le pipeline de middleware.
  4.  Vous DEVEZ utiliser RequireAuthorization() ou l'attribut [Authorize] pour protéger les points de terminaison.

  PROBLÈMES COURANTS RENCONTRÉS LORS DE L'INTÉGRATION

  Problème 1 : Valeurs de configuration introuvables
  Problème : Domain ou Audience est nul lors de l'exécution
  Solution : Assurez-vous qu'appsettings.json contient la section Auth0 avec les valeurs correctes

  Problème 2 : Problèmes d'ordre des middlewares
  Problème : L'authentification ne fonctionne pas malgré une configuration correcte
  Solution : Assurez-vous que UseAuthentication() vient avant UseAuthorization() dans Program.cs

  Problème 3 : Erreurs 401 Non autorisé
  Problème : Les jetons valides sont rejetés
  Solution : Vérifiez que Domain n'inclut pas https:// et qu'Audience correspond exactement à l'identifiant API Auth0

  Problème 4 : Erreurs de certificat HTTPS en développement
  Problème : Erreurs SSL/TLS lors de l'exécution locale
  Solution : Exécutez `dotnet dev-certs https --trust` pour faire confiance au certificat de développement
  ```
</Accordion>

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d'avoir installé ce qui suit :

  * **[Trousse de développement logiciel (SDK) .NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)** ou une version plus récente
  * Votre IDE préféré (Visual Studio 2022, VS Code ou Rider)

  **Compatibilité des versions .NET :** Ce Démarrage rapide fonctionne avec **.NET 8.0** et les versions plus récentes.
</Note>

<div id="get-started">
  ## Mise en route
</div>

Ce démarrage rapide vous montre comment ajouter l’authentification Auth0 basée sur des JWT à une API Web ASP.NET Core. Vous allez créer une API sécurisée avec des points de terminaison protégés à l’aide de la trousse de développement logiciel (SDK) Auth0 ASP.NET Core API.

<Steps>
  <Step title="Créer un nouveau projet" stepNumber={1}>
    Créez un nouveau projet d’API Web ASP.NET Core pour ce Démarrage rapide

    ```bash theme={null}
    dotnet new webapi -n Auth0Api
    ```

    Ouvrir le projet

    ```bash theme={null}
    cd Auth0Api
    ```
  </Step>

  <Step title="Installez la trousse de développement logiciel (SDK) d'Auth0" stepNumber={2}>
    ```bash theme={null}
    dotnet add package Auth0.AspNetCore.Authentication.Api
    ```
  </Step>

  <Step title="Configurez votre API Auth0" stepNumber={3}>
    Ensuite, vous devez créer une nouvelle API sur votre locataire Auth0 et ajouter la configuration à votre projet.

    Vous pouvez choisir de le faire automatiquement en exécutant une commande CLI ou manuellement via le tableau de bord :

    <Tabs>
      <Tab title="CLI">
        Exécutez la commande suivante dans le répertoire racine de votre projet pour créer une API Auth0 et mettre à jour votre fichier `appsettings.json` :

        <Tabs>
          <Tab title="Mac/Linux">
            ```bash theme={null}
            AUTH0_API_NAME="My ASP.NET Core API" && \
            AUTH0_API_IDENTIFIER="https://my-api" && \
            brew tap auth0/auth0-cli && \
            brew install auth0 && \
            auth0 login --no-input && \
            auth0 apis create -n "${AUTH0_API_NAME}" -i "${AUTH0_API_IDENTIFIER}" --offline-access --token-lifetime 86400 --signing-alg RS256 --json > auth0-api-details.json && \
            DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && \
            AUDIENCE=$(jq -r '.identifier' auth0-api-details.json) && \
            jq --arg domain "$DOMAIN" --arg audience "$AUDIENCE" \
              '.Auth0.Domain = $domain | .Auth0.Audience = $audience' \
              appsettings.json > appsettings.tmp.json && \
            mv appsettings.tmp.json appsettings.json && \
            rm auth0-api-details.json && \
            echo "✅ appsettings.json mis à jour avec les détails de votre API Auth0 :" && \
            cat appsettings.json
            ```
          </Tab>

          <Tab title="Windows (PowerShell)">
            ```powershell theme={null}
            $ApiName = "My ASP.NET Core API"
            $ApiIdentifier = "https://my-api"
            $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/auth0/auth0-cli/releases/latest"
            $latestVersion = $latestRelease.tag_name
            $version = $latestVersion -replace "^v"
            Invoke-WebRequest -Uri "https://github.com/auth0/auth0-cli/releases/download/${latestVersion}/auth0-cli_${version}_Windows_x86_64.zip" -OutFile ".\auth0.zip"
            Expand-Archive ".\auth0.zip" .\
            [System.Environment]::SetEnvironmentVariable('PATH', $Env:PATH + ";${pwd}")
            auth0 login --no-input
            auth0 apis create -n "$ApiName" -i "$ApiIdentifier" --offline-access --token-lifetime 86400 --signing-alg RS256 --json | Set-Content -Path auth0-api-details.json
            $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name
            $Audience = (Get-Content -Raw auth0-api-details.json | ConvertFrom-Json).identifier
            $Config = Get-Content -Raw appsettings.json | ConvertFrom-Json
            if (-not $Config.Auth0) { $Config | Add-Member -MemberType NoteProperty -Name Auth0 -Value @{} }
            $Config.Auth0.Domain = $Domain
            $Config.Auth0.Audience = $Audience
            $Config | ConvertTo-Json -Depth 10 | Set-Content appsettings.json
            Remove-Item auth0-api-details.json
            Write-Output "✅ appsettings.json mis à jour avec les détails de votre API Auth0 :"
            Get-Content appsettings.json
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Tableau de bord">
        Avant de commencer, ajoutez la configuration d’Auth0 à votre fichier `appsettings.json`.

        ```json appsettings.json theme={null}
        {
          "Logging": {
            "LogLevel": {
              "Default": "Information",
              "Microsoft.AspNetCore": "Warning"
            }
          },
          "AllowedHosts": "*",
          "Auth0": {
            "Domain": "YOUR_AUTH0_DOMAIN",
            "Audience": "YOUR_AUTH0_API_IDENTIFIER"
          }
        }
        ```

        1. Accédez à [Auth0 Dashboard](https://manage.auth0.com) → **Applications** → **APIs**
        2. Cliquez sur **Create API**
        3. Entrez les détails de votre API :
           * **Name** : My ASP.NET Core API
           * **Identifier** : `https://my-api` (cela devient votre Audience)
           * **Signing Algorithm** : RS256
        4. Cliquez sur **Create**
        5. Remplacez `YOUR_AUTH0_DOMAIN` dans `appsettings.json` par votre **Domaine** indiqué dans l’onglet Test (p. ex. `your-tenant.auth0.com`)
        6. Remplacez `YOUR_AUTH0_API_IDENTIFIER` dans `appsettings.json` par votre **Identifier** (p. ex. `https://my-api`)

        <Info>
          Votre **Domaine** ne doit pas inclure `https://` — utilisez uniquement le nom de domaine (p. ex. `your-tenant.auth0.com`).

          L’**Audience** (identifiant d’API) est un identificateur unique pour votre API et peut être n’importe quel URI valide. Il n’a pas besoin d’être une URL accessible publiquement.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurer l’authentification" stepNumber={4}>
    Remplacez l’intégralité du contenu de `Program.cs` par le code suivant :

    ```csharp Program.cs lines theme={null}
    using Auth0.AspNetCore.Authentication.Api;
    using Microsoft.AspNetCore.Authentication.JwtBearer;

    var builder = WebApplication.CreateBuilder(args);

    builder.Services.AddAuth0ApiAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Domain"];
        options.JwtBearerOptions = new JwtBearerOptions
        {
            Audience = builder.Configuration["Auth0:Audience"]
        };
    });

    builder.Services.AddAuthorization();

    var app = builder.Build();

    if (!app.Environment.IsDevelopment())
    {
        app.UseHttpsRedirection();
    }

    app.UseAuthentication();
    app.UseAuthorization();

    app.Run();
    ```
  </Step>

  <Step title="Créez des points de terminaison publics et protégés" stepNumber={5}>
    Ajoutez des points de terminaison pour tester l’authentification. Ajoutez le code suivant dans `Program.cs` avant `app.Run()` :

    ```csharp Program.cs theme={null}
    // Point de terminaison public - aucune authentification requise
    app.MapGet("/api/public", () => 
        Results.Ok(new { Message = "This endpoint is public" }))
        .WithName("GetPublic");

    // Point de terminaison protégé - requiert une authentification
    app.MapGet("/api/private", () => 
        Results.Ok(new { Message = "This endpoint requires authentication" }))
        .RequireAuthorization()
        .WithName("GetPrivate");
    ```
  </Step>

  <Step title="Exécuter votre API" stepNumber={6}>
    ```bash theme={null}
    dotnet run
    ```

    Votre API s’exécute maintenant à l’adresse `https://localhost:7190` (ou une adresse similaire — vérifiez la sortie de la console pour connaître l’URL exacte).
  </Step>
</Steps>

<Check>
  **Point de contrôle**

  Vous devriez maintenant avoir une API protégée par Auth0 entièrement fonctionnelle qui s’exécute sur votre [localhost](https://localhost:7190/)
</Check>

***

<div id="advanced-usage">
  ## Utilisation avancée
</div>

<Accordion title="Appeler des API protégées">
  Testez vos points de terminaison protégés avec un jeton d’accès.

  **1. Obtenez un jeton d’accès** auprès d’Auth0 à l’aide du flux Client Credentials :

  ```bash theme={null}
  curl --request POST \
    --url https://YOUR_DOMAIN/oauth/token \
    --header 'content-type: application/json' \
    --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials"}'
  ```

  <Info>
    Pour obtenir `YOUR_CLIENT_ID` et `YOUR_CLIENT_SECRET`, créez une Application Machine to Machine dans le [Auth0 Dashboard](https://manage.auth0.com/#/applications) et autorisez-la à accéder à votre API.
  </Info>

  **2. Testez le point de terminaison public** (devrait renvoyer 200 OK) :

  ```bash theme={null}
  curl https://localhost:7190/api/public
  ```

  **3. Testez le point de terminaison protégé sans authentification** (devrait renvoyer 401 Unauthorized) :

  ```bash theme={null}
  curl https://localhost:7190/api/private
  ```

  **4. Appelez le point de terminaison protégé avec le jeton :**

  ```bash theme={null}
  curl https://localhost:7190/api/private \
    --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
  ```
</Accordion>

<Accordion title="Utiliser des points de terminaison basés sur des contrôleurs">
  Pour des API plus volumineuses, utilisez des contrôleurs plutôt que des points de terminaison d’API minimales.

  **1. Ajoutez la prise en charge des contrôleurs :**

  ```csharp Program.cs theme={null}
  builder.Services.AddControllers();

  var app = builder.Build();

  if (!app.Environment.IsDevelopment())
  {
      app.UseHttpsRedirection();
  }

  app.UseAuthentication();
  app.UseAuthorization();

  app.MapControllers();

  app.Run();
  ```

  **2. Créez un contrôleur :**

  Créez `Controllers/MessagesController.cs` :

  ```csharp Controllers/MessagesController.cs theme={null}
  using Microsoft.AspNetCore.Authorization;
  using Microsoft.AspNetCore.Mvc;

  namespace Auth0Api.Controllers;

  [ApiController]
  [Route("api/[controller]")]
  public class MessagesController : ControllerBase
  {
      [HttpGet]
      public IActionResult GetPublic()
      {
          return Ok(new { Message = "This endpoint is public" });
      }

      [Authorize]
      [HttpGet("private")]
      public IActionResult GetPrivate()
      {
          var userId = User.FindFirst("sub")?.Value;
          return Ok(new { Message = "This endpoint is protected", UserId = userId });
      }

      [Authorize(Policy = "read:messages")]
      [HttpGet("messages")]
      public IActionResult GetMessages()
      {
          return Ok(new { Messages = new[] { "Message 1", "Message 2" } });
      }
  }
  ```
</Accordion>

<Accordion title="Protéger des routes avec une autorisation basée sur les scopes">
  Protégez des points de terminaison en fonction de scopes spécifiques présents dans le jeton d’accès.

  **1. Définissez des scopes dans votre API Auth0 :**

  Dans le [Auth0 Dashboard](https://manage.auth0.com) → APIs → Your API → Permissions, ajoutez des scopes :

  * `read:messages` - Lire les messages
  * `write:messages` - Écrire des messages

  **2. Configurez les stratégies d’autorisation :**

  ```csharp Program.cs theme={null}
  builder.Services.AddAuthorization(options =>
  {
      options.AddPolicy("read:messages", policy =>
          policy.RequireClaim("scope", "read:messages"));
      
      options.AddPolicy("write:messages", policy =>
          policy.RequireClaim("scope", "write:messages"));
  });
  ```

  **3. Appliquez les stratégies aux points de terminaison :**

  ```csharp theme={null}
  app.MapGet("/api/messages", () => 
      Results.Ok(new { Messages = new[] { "Message 1", "Message 2" } }))
      .RequireAuthorization("read:messages");

  app.MapPost("/api/messages", () => 
      Results.Created("/api/messages/1", new { Id = 1, Text = "New message" }))
      .RequireAuthorization("write:messages");
  ```

  Lorsque vous demandez un jeton d’accès, incluez le scope requis :

  ```bash theme={null}
  curl --request POST \
    --url https://YOUR_DOMAIN/oauth/token \
    --header 'content-type: application/json' \
    --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials","scope":"read:messages write:messages"}'
  ```
</Accordion>

<Accordion title="Utiliser DPoP pour une sécurité renforcée">
  DPoP (Demonstration of Proof-of-Possession) lie les jetons d’accès à des clés cryptographiques, ce qui empêche le vol de jetons et les attaques par relecture.

  **Activez la prise en charge de DPoP :**

  ```csharp Program.cs theme={null}
  builder.Services.AddAuth0ApiAuthentication(options =>
  {
      options.Domain = builder.Configuration["Auth0:Domain"];
      options.JwtBearerOptions = new JwtBearerOptions
      {
          Audience = builder.Configuration["Auth0:Audience"]
      };
  }).WithDPoP();  // Activer DPoP avec les paramètres par défaut
  ```

  **Modes DPoP :**

  Accepter à la fois les jetons DPoP et Bearer (par défaut) :

  ```csharp theme={null}
  using Auth0.AspNetCore.Authentication.Api.DPoP;

  .WithDPoP(dpopOptions =>
  {
      dpopOptions.Mode = DPoPModes.Allowed;
  });
  ```

  Accepter uniquement les jetons DPoP, rejeter les jetons Bearer :

  ```csharp theme={null}
  using Auth0.AspNetCore.Authentication.Api.DPoP;

  .WithDPoP(dpopOptions =>
  {
      dpopOptions.Mode = DPoPModes.Required;
  });
  ```

  Configurer les paramètres de validation temporelle :

  ```csharp theme={null}
  .WithDPoP(dpopOptions =>
  {
      dpopOptions.Mode = DPoPModes.Allowed;
      dpopOptions.IatOffset = 300;  // Autoriser une preuve DPoP âgée jusqu’à 5 minutes
      dpopOptions.Leeway = 30;      // Tolérance de dérive d’horloge de 30 secondes
  });
  ```

  <Info>
    Pour en savoir plus sur DPoP, consultez la [documentation DPoP Auth0](https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop).
  </Info>
</Accordion>

<Accordion title="Implémenter des stratégies d’autorisation personnalisées">
  Créez des stratégies d’autorisation réutilisables pour répondre à des exigences complexes.

  **1. Créez une exigence personnalisée :**

  ```csharp Authorization/HasScopeRequirement.cs theme={null}
  using Microsoft.AspNetCore.Authorization;

  namespace Auth0Api.Authorization;

  public class HasScopeRequirement : IAuthorizationRequirement
  {
      public string Scope { get; }
      public string Issuer { get; }

      public HasScopeRequirement(string scope, string issuer)
      {
          Scope = scope;
          Issuer = issuer;
      }
  }
  ```

  **2. Créez un gestionnaire :**

  ```csharp Authorization/HasScopeHandler.cs theme={null}
  using Microsoft.AspNetCore.Authorization;

  namespace Auth0Api.Authorization;

  public class HasScopeHandler : AuthorizationHandler<HasScopeRequirement>
  {
      protected override Task HandleRequirementAsync(
          AuthorizationHandlerContext context,
          HasScopeRequirement requirement)
      {
          if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
          {
              return Task.CompletedTask;
          }

          var scopes = context.User
              .FindFirst(c => c.Type == "scope" && c.Issuer == requirement.Issuer)?
              .Value.Split(' ');

          if (scopes?.Any(s => s == requirement.Scope) == true)
          {
              context.Succeed(requirement);
          }

          return Task.CompletedTask;
      }
  }
  ```

  **3. Enregistrez et utilisez la stratégie :**

  ```csharp Program.cs theme={null}
  using Auth0Api.Authorization;

  var builder = WebApplication.CreateBuilder(args);

  var domain = $"https://{builder.Configuration["Auth0:Domain"]}";

  builder.Services.AddAuth0ApiAuthentication(options =>
  {
      options.Domain = builder.Configuration["Auth0:Domain"];
      options.JwtBearerOptions = new JwtBearerOptions
      {
          Audience = builder.Configuration["Auth0:Audience"]
      };
  });

  builder.Services.AddAuthorization(options =>
  {
      options.AddPolicy("read:messages", policy =>
          policy.Requirements.Add(new HasScopeRequirement("read:messages", domain)));
  });

  builder.Services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();

  var app = builder.Build();
  // ... reste de la configuration
  ```
</Accordion>

<Accordion title="Accéder à l’information sur l’utilisateur">
  Extrayez les renseignements sur l’utilisateur à partir du jeton d’authentification.

  ```csharp theme={null}
  app.MapGet("/api/user-info", (HttpContext context) =>
  {
      var userId = context.User.FindFirst("sub")?.Value;
      var email = context.User.FindFirst("email")?.Value;
      var name = context.User.FindFirst("name")?.Value;
      var scopes = context.User.FindAll("scope")
          .SelectMany(c => c.Value.Split(' '))
          .Distinct();

      return Results.Ok(new
      {
          UserId = userId,
          Email = email,
          Name = name,
          Scopes = scopes
      });
  })
  .RequireAuthorization();
  ```
</Accordion>

<Accordion title="Validation personnalisée de jetons">
  Personnalisez les paramètres de validation des jetons JWT pour répondre à des exigences spécifiques.

  ```csharp Program.cs theme={null}
  using Microsoft.IdentityModel.Tokens;
  using System.Security.Claims;

  builder.Services.AddAuth0ApiAuthentication(options =>
  {
      options.Domain = builder.Configuration["Auth0:Domain"];
      options.JwtBearerOptions = new JwtBearerOptions
      {
          Audience = builder.Configuration["Auth0:Audience"],
          
          TokenValidationParameters = new TokenValidationParameters
          {
              ValidateIssuerSigningKey = true,
              ValidateIssuer = true,
              ValidateAudience = true,
              ValidateLifetime = true,
              ClockSkew = TimeSpan.FromMinutes(5),
              NameClaimType = ClaimTypes.NameIdentifier,
              RoleClaimType = "https://my-app.com/roles"
          },
          
          Events = new JwtBearerEvents
          {
              OnAuthenticationFailed = context =>
              {
                  Console.WriteLine($"Authentication failed: {context.Exception.Message}");
                  return Task.CompletedTask;
              },
              
              OnTokenValidated = context =>
              {
                  var userId = context.Principal?.FindFirst("sub")?.Value;
                  Console.WriteLine($"Token validated for user: {userId}");
                  return Task.CompletedTask;
              }
          }
      };
  });
  ```
</Accordion>

***

<div id="additional-resources">
  ## Ressources supplémentaires
</div>

<CardGroup cols={3}>
  <Card title="Documentation du SDK" icon="book" href="https://github.com/auth0/aspnetcore-api">
    Documentation complète du SDK et référence de l’API
  </Card>

  <Card title="Guide de migration" icon="arrow-right-arrow-left" href="https://github.com/auth0/aspnetcore-api/blob/master/MIGRATION.md">
    Migrez à partir de l’authentification JWT Bearer
  </Card>

  <Card title="Exemples de code" icon="code" href="https://github.com/auth0/aspnetcore-api/blob/master/EXAMPLES.md">
    Exemples de code détaillés et modèles
  </Card>

  <Card title="Documentation DPoP" icon="shield" href="https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop">
    En savoir plus sur la sécurité par preuve de possession
  </Card>

  <Card title="Meilleures pratiques pour les jetons" icon="key" href="https://auth0.com/docs/secure/tokens/token-best-practices">
    Meilleures pratiques de sécurité pour les jetons
  </Card>

  <Card title="Forum communautaire" icon="comments" href="https://community.auth0.com/">
    Obtenez de l’aide auprès de la communauté Auth0
  </Card>
</CardGroup>

***

<div id="common-issues">
  ## Problèmes courants
</div>

<AccordionGroup>
  <Accordion title="401 Non autorisé - Audience non valide">
    **Problème :** La validation du jeton échoue avec une erreur de non-correspondance de l’audience.

    **Solution :** Assurez-vous que `Audience` dans `appsettings.json` correspond exactement à l’identifiant de votre API Auth0. La revendication d’audience dans le jeton doit correspondre à cette valeur.

    ```json theme={null}
    {
      "Auth0": {
        "Audience": "https://my-api"  // Doit correspondre à l’Identifiant de l’API Auth0
      }
    }
    ```
  </Accordion>

  <Accordion title="401 Non autorisé - Émetteur non valide">
    **Problème :** La validation du jeton échoue avec une erreur liée à l’émetteur.

    **Solution :** Vérifiez que votre Domaine est correct et ne contient pas `https://`. La bibliothèque construit automatiquement l’autorité sous la forme `https://{Domain}`.

    ```json theme={null}
    {
      "Auth0": {
        "Domain": "your-tenant.auth0.com"  // Sans https://
      }
    }
    ```
  </Accordion>

  <Accordion title="Valeurs de configuration introuvables">
    **Problème :** `ArgumentNullException: Value cannot be null. (Parameter 'Domain')` ou similaire.

    **Solution :** Assurez-vous que `appsettings.json` contient la section Auth0 avec les valeurs de Domaine et d’audience. Vérifiez que la configuration est lue correctement :

    ```csharp theme={null}
    builder.Services.AddAuth0ApiAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Domain"]
            ?? throw new InvalidOperationException("Auth0:Domain is required");
        options.JwtBearerOptions = new JwtBearerOptions
        {
            Audience = builder.Configuration["Auth0:Audience"]
                ?? throw new InvalidOperationException("Auth0:Audience is required")
        };
    });
    ```
  </Accordion>

  <Accordion title="Erreurs de certificat HTTPS en développement">
    **Problème :** Erreurs de certificat SSL/TLS lors de l’exécution en local.

    **Solution :** Faites approuver le certificat de développement :

    ```bash theme={null}
    dotnet dev-certs https --trust
    ```

    Ou générez un nouveau certificat :

    ```bash theme={null}
    dotnet dev-certs https --clean
    dotnet dev-certs https --trust
    ```
  </Accordion>

  <Accordion title="Problèmes d’ordre du middleware">
    **Problème :** L’authentification ne fonctionne pas malgré une configuration correcte.

    **Solution :** Assurez-vous que le middleware est dans le bon ordre. `UseAuthentication()` doit être appelé avant `UseAuthorization()` :

    ```csharp theme={null}
    app.UseAuthentication();  // Doit être appelé avant UseAuthorization
    app.UseAuthorization();
    app.MapControllers();
    ```
  </Accordion>

  <Accordion title="Scopes qui ne fonctionnent pas dans les stratégies d’autorisation">
    **Problème :** Les stratégies d’autorisation basées sur les scopes échouent toujours.

    **Solution :** Assurez-vous que votre jeton d’accès inclut les scopes requis. Lors de la demande d’un jeton, spécifiez les scopes :

    ```bash theme={null}
    curl --request POST \
      --url https://YOUR_DOMAIN/oauth/token \
      --data '{"client_id":"...","client_secret":"...","audience":"...","grant_type":"client_credentials","scope":"read:messages write:messages"}'
    ```

    Vérifiez aussi que les scopes sont définis dans les paramètres de votre API Auth0 (Dashboard → APIs → Your API → Permissions).
  </Accordion>
</AccordionGroup>

***

<div id="sample-application">
  ## Application d'exemple
</div>

Une application d'exemple complète démontrant toutes les fonctionnalités est disponible dans le dépôt du SDK (Trousse de développement logiciel).

<Card title="Application de test" icon="github" href="https://github.com/auth0/aspnetcore-api/tree/master/Auth0.AspNetCore.Authentication.Api.Playground">
  Inclut des points de terminaison publics et protégés, la prise en charge de DPoP, l'intégration à Swagger UI et une collection Postman
</Card>

Clonez et exécutez :

```bash theme={null}
git clone https://github.com/auth0/aspnetcore-api.git
cd aspnetcore-api/Auth0.AspNetCore.Authentication.Api.Playground
# Mettez à jour appsettings.json avec votre configuration Auth0
dotnet run
```
