Passer au contenu principal
Ce guide de démarrage rapide est actuellement en bêta. N’hésitez pas à nous faire part de vos commentaires!

Utiliser l’IA pour intégrer Auth0

Si vous utilisez un assistant IA de codage comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification Auth0 en quelques minutes à l’aide des agent skills.Installer :
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-aspnetcore-api
Ensuite, demandez à votre assistant IA :
Add Auth0 JWT authentication to my ASP.NET Core Web API
Votre assistant IA créera automatiquement votre API Auth0, récupérera les identifiants, installera le SDK d’authentification API Auth0 pour ASP.NET Core, configurera l’authentification JWT Bearer et mettra en œuvre des points de terminaison d’API protégés. Documentation complète sur les agent skills →
Prérequis : Avant de commencer, assurez-vous d’avoir installé ce qui suit :
  • .NET 8.0 SDK ou une version ultérieure
  • Votre IDE préféré (Visual Studio 2022, VS Code ou Rider)
Compatibilité des versions de .NET : Ce guide de démarrage rapide fonctionne avec .NET 8.0 et les versions ultérieures.

Premiers pas

Ce guide de démarrage rapide montre comment ajouter l’authentification JWT d’Auth0 à une API Web ASP.NET Core. Vous créerez une API sécurisée avec des points de terminaison protégés à l’aide du SDK API ASP.NET Core d’Auth0.
1

Créer un nouveau projet

Créez un nouveau projet d’API web ASP.NET Core pour ce guide de démarrage rapide
dotnet new webapi -n Auth0Api
Ouvrir le projet
cd Auth0Api
2

Installez le SDK Auth0

dotnet add package Auth0.AspNetCore.Authentication.Api
3

Configurez votre API Auth0

Ensuite, vous devez créer une nouvelle API sur votre tenant Auth0 et ajouter la configuration à votre projet.Vous pouvez effectuer cette opération automatiquement en exécutant une commande CLI ou manuellement via le tableau de bord :
Exécutez la commande shell suivante à la racine du projet pour créer une API Auth0 et mettre à jour votre fichier appsettings.json :
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 updated with your Auth0 API details:" && \
cat appsettings.json
4

Configurer l’authentification

Remplacez l’intégralité du contenu de Program.cs par le code suivant :
Program.cs
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();
5

Créer des points de terminaison publics et protégés

Ajoutez des points de terminaison pour tester l’authentification. Ajoutez le code suivant à Program.cs avant app.Run() :
Program.cs
// 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é - authentification requise
app.MapGet("/api/private", () => 
    Results.Ok(new { Message = "This endpoint requires authentication" }))
    .RequireAuthorization()
    .WithName("GetPrivate");
6

Exécutez votre API

dotnet run
Votre API fonctionne maintenant à l’adresse https://localhost:7190 (ou à une URL semblable - vérifiez la sortie de la console pour connaître l’URL exacte).
Point de contrôleVous devriez maintenant avoir une API protégée par Auth0 entièrement fonctionnelle, accessible sur votre localhost

Utilisation avancée

Testez vos points de terminaison protégés à l’aide d’un jeton d’accès.1. Obtenez un jeton d’accès auprès d’Auth0 à l’aide du flux Client Credentials :
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"}'
Pour obtenir YOUR_CLIENT_ID et YOUR_CLIENT_SECRET, créez une application Machine-to-Machine dans le tableau de bord Auth0 et autorisez-la à accéder à votre API.
2. Testez le point de terminaison public (devrait renvoyer 200 OK) :
curl https://localhost:7190/api/public
3. Testez le point de terminaison protégé sans authentification (devrait renvoyer 401 Unauthorized) :
curl https://localhost:7190/api/private
4. Appelez le point de terminaison protégé avec le jeton :
curl https://localhost:7190/api/private \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Pour les API plus volumineuses, utilisez des contrôleurs plutôt que des points de terminaison d’API minimaux.1. Ajoutez la prise en charge des contrôleurs :
Program.cs
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 :
Controllers/MessagesController.cs
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" } });
    }
}
Protégez les points de terminaison en fonction de portées précises dans le jeton d’accès.1. Définissez des portées dans votre API Auth0 :Dans le tableau de bord Auth0 → APIs → Your API → Permissions, ajoutez des portées :
  • read:messages - Lire les messages
  • write:messages - Écrire des messages
2. Configurez les politiques d’autorisation :
Program.cs
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 politiques aux points de terminaison :
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 la portée requise :
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"}'
DPoP (Demonstration of Proof-of-Possession) associe les jetons d’accès à des clés cryptographiques, ce qui empêche le vol de jetons et les attaques par rejeu.Activer la prise en charge de DPoP :
Program.cs
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) :
using Auth0.AspNetCore.Authentication.Api.DPoP;

.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Allowed;
});
Accepter uniquement les jetons DPoP et rejeter les jetons Bearer :
using Auth0.AspNetCore.Authentication.Api.DPoP;

.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Required;
});
Configurer les paramètres de validation temporelle :
.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Allowed;
    dpopOptions.IatOffset = 300;  // Autoriser une preuve DPoP datant d’au plus 5 minutes
    dpopOptions.Leeway = 30;      // Tolérance de 30 secondes pour le décalage de l’horloge
});
Pour en savoir plus sur DPoP, consultez la documentation Auth0 sur DPoP.
Créer des politiques d’autorisation réutilisables pour répondre à des exigences complexes.1. Créer une exigence personnalisée :
Authorization/HasScopeRequirement.cs
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éer un gestionnaire :
Authorization/HasScopeHandler.cs
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. Enregistrer et utiliser la politique :
Program.cs
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
Extrayez les renseignements de l’utilisateur à partir du jeton authentifié.
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();
Personnalisez les paramètres de validation du jeton JWT en fonction de vos besoins particuliers.
Program.cs
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;
            }
        }
    };
});

Ressources supplémentaires

Documentation du SDK

Documentation complète du SDK et référence de l’API

Guide de migration

Migrer à partir de l’authentification JWT Bearer

Exemples de code

Exemples de code et modèles complets

Documentation sur DPoP

En savoir plus sur la sécurité par preuve de possession

Bonnes pratiques relatives aux jetons

Bonnes pratiques de sécurité pour les jetons

Forum de la communauté

Obtenez de l’aide de la communauté Auth0

Problèmes courants

Problème : La validation du jeton échoue en raison d’une incompatibilité de l’audience.Solution : Assurez-vous que Audience dans appsettings.json correspond exactement à l’identifiant de votre API Auth0. La revendication d’audience du jeton doit correspondre à cette valeur.
{
  "Auth0": {
    "Audience": "https://my-api"  // Doit correspondre à l’identifiant de l’API Auth0
  }
}
Problème : La validation du jeton échoue en raison d’une erreur liée à l’émetteur.Solution : Vérifiez que votre domaine est correct et qu’il n’inclut pas https://. La bibliothèque construit automatiquement l’autorité sous la forme https://{Domain}.
{
  "Auth0": {
    "Domain": "your-tenant.auth0.com"  // Sans https://
  }
}
Problème : ArgumentNullException: Value cannot be null. (Parameter 'Domain') ou un message semblable.Solution : Assurez-vous que appsettings.json contient la section Auth0 avec les valeurs Domain et Audience. Vérifiez aussi que la configuration est bien lue :
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")
    };
});
Problème : Des erreurs de certificat SSL/TLS surviennent lors de l’exécution en local.Solution : Faites approuver le certificat de développement :
dotnet dev-certs https --trust
Ou générez un nouveau certificat :
dotnet dev-certs https --clean
dotnet dev-certs https --trust
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() :
app.UseAuthentication();  // Doit être avant UseAuthorization
app.UseAuthorization();
app.MapControllers();
Problème : Les politiques d’autorisation basées sur les portées échouent systématiquement.Solution : Assurez-vous que votre jeton d’accès comprend les portées requises. Lorsque vous demandez un jeton, précisez les portées :
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 portées sont définies dans les paramètres de votre API Auth0 (tableau de bord Auth0 → APIs → Your API → Permissions).

Exemple d’application

Un exemple d’application complet illustrant toutes les fonctionnalités est disponible dans le dépôt du SDK.

Application de démonstration

Comprend des points de terminaison publics et protégés, la prise en charge de DPoP, l’intégration de Swagger UI et une collection Postman
Clonez et exécutez :
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