Saltar al contenido principal
Esta guía de inicio rápido está actualmente en Beta. ¡Nos encantaría conocer sus comentarios!

Usa IA para integrar Auth0

Si usa un asistente de código con IA como Claude Code, Cursor o GitHub Copilot, puede agregar la autenticación de Auth0 automáticamente en minutos con agent skills.Instalar:
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-aspnetcore-api
Luego, pídale a su asistente de IA:
Add Auth0 JWT authentication to my ASP.NET Core Web API
Su asistente de IA creará automáticamente su API de Auth0, recuperará las credenciales, instalará el SDK de la API de autenticación de Auth0 para ASP.NET Core, configurará la autenticación JWT Bearer e implementará endpoints de API protegidos. Documentación completa de agent skills →
Requisitos previos: Antes de comenzar, asegúrese de tener instalado lo siguiente:
  • SDK de .NET 8.0 o superior
  • Su IDE preferido (Visual Studio 2022, VS Code o Rider)
Compatibilidad de versiones de .NET: Esta guía de inicio rápido funciona con .NET 8.0 y versiones posteriores.

Primeros pasos

Esta guía de inicio rápido muestra cómo agregar autenticación JWT de Auth0 a una API web de ASP.NET Core. Creará una API segura con endpoints protegidos mediante el SDK de API de Auth0 para ASP.NET Core.
1

Crear un nuevo proyecto

Cree un nuevo proyecto de API web de ASP.NET Core para esta guía de inicio rápido
dotnet new webapi -n Auth0Api
Abrir el proyecto
cd Auth0Api
2

Instala el SDK de Auth0

dotnet add package Auth0.AspNetCore.Authentication.Api
3

Configura tu API de Auth0

A continuación, debes crear una nueva API en tu tenant de Auth0 y agregar la configuración a tu proyecto.Puede hacerlo automáticamente ejecutando un comando de CLI o de forma manual a través del Dashboard:
Ejecute el siguiente comando de shell desde el directorio raíz de su proyecto para crear una API de Auth0 y actualizar el archivo 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

Configurar la autenticación

Reemplace todo el contenido de Program.cs con el siguiente código:
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

Crear endpoints públicos y protegidos

Agregue endpoints para probar la autenticación. Agregue el siguiente código a Program.cs antes de app.Run():
Program.cs
// Endpoint público - no requiere autenticación
app.MapGet("/api/public", () => 
    Results.Ok(new { Message = "This endpoint is public" }))
    .WithName("GetPublic");

// Endpoint protegido - requiere autenticación
app.MapGet("/api/private", () => 
    Results.Ok(new { Message = "This endpoint requires authentication" }))
    .RequireAuthorization()
    .WithName("GetPrivate");
6

Inicie la API

dotnet run
Tu API ya está en ejecución en https://localhost:7190 (o una URL similar; consulta la salida de la consola para ver la URL exacta).
Punto de verificaciónAhora deberías tener una API protegida por Auth0 totalmente funcional ejecutándose en tu localhost

Uso avanzado

Prueba tus endpoints protegidos con un token de acceso.1. Obtén un token de acceso de Auth0 mediante el flujo 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"}'
Para obtener YOUR_CLIENT_ID y YOUR_CLIENT_SECRET, crea una aplicación de máquina a máquina en el Auth0 Dashboard y autorízala para tu API.
2. Prueba el endpoint público (debe devolver 200 OK):
curl https://localhost:7190/api/public
3. Prueba el endpoint protegido sin autenticación (debe devolver 401 Unauthorized):
curl https://localhost:7190/api/private
4. Llama al endpoint protegido con el token:
curl https://localhost:7190/api/private \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Para APIs más grandes, usa controladores en lugar de endpoints de Minimal APIs.1. Agrega compatibilidad con controladores:
Program.cs
builder.Services.AddControllers();

var app = builder.Build();

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

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

app.MapControllers();

app.Run();
2. Crea un controlador:Crea 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" } });
    }
}
Protege endpoints en función de alcances específicos en el token de acceso.1. Define alcances en tu API de Auth0:En el Auth0 Dashboard → APIs → Tu API → Permissions, agrega los alcances:
  • read:messages - Leer mensajes
  • write:messages - Escribir mensajes
2. Configura políticas de autorización:
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. Aplica las políticas a los endpoints:
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");
Al solicitar un token de acceso, incluye el scope requerido:
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 (Demostración de prueba de posesión) vincula los tokens de acceso a claves criptográficas, lo que evita el robo de tokens y los ataques de repetición.Habilite la compatibilidad con DPoP:
Program.cs
builder.Services.AddAuth0ApiAuthentication(options =>
{
    options.Domain = builder.Configuration["Auth0:Domain"];
    options.JwtBearerOptions = new JwtBearerOptions
    {
        Audience = builder.Configuration["Auth0:Audience"]
    };
}).WithDPoP();  // Habilita DPoP con la configuración predeterminada
Modos de DPoP:Acepte tokens DPoP y Bearer (predeterminado):
using Auth0.AspNetCore.Authentication.Api.DPoP;

.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Allowed;
});
Acepte solo tokens DPoP y rechace los tokens Bearer:
using Auth0.AspNetCore.Authentication.Api.DPoP;

.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Required;
});
Configure los parámetros de validación de tiempo:
.WithDPoP(dpopOptions =>
{
    dpopOptions.Mode = DPoPModes.Allowed;
    dpopOptions.IatOffset = 300;  // Permite pruebas de DPoP con hasta 5 minutos de antigüedad
    dpopOptions.Leeway = 30;      // Tolerancia de 30 segundos para el desfase del reloj
});
Obtenga más información sobre DPoP en la documentación de DPoP de Auth0.
Cree políticas de autorización reutilizables para requisitos complejos.1. Cree un requisito personalizado:
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. Cree un manejador:
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. Registre y use la política:
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();
// ... resto de la configuración
Extraiga la información del usuario del token autenticado.
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();
Personalice los parámetros de validación del token JWT para requisitos específicos.
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;
            }
        }
    };
});

Recursos adicionales

Documentación del SDK

Documentación completa del SDK y referencia de la API

Guía de migración

Migre desde la autenticación con JWT Bearer

Ejemplos de código

Ejemplos y patrones de código completos

Documentación de DPoP

Más información sobre la seguridad con prueba de posesión

Prácticas recomendadas para tokens

Prácticas recomendadas de seguridad para tokens

Foro de la comunidad

Obtenga ayuda de la comunidad de Auth0

Problemas comunes

Problema: La validación del token falla porque la audiencia no coincide.Solución: Asegúrate de que Audience en appsettings.json coincida exactamente con el identificador de tu API de Auth0. El claim audience del token debe coincidir con este valor.
{
  "Auth0": {
    "Audience": "https://my-api"  // Debe coincidir con el identificador de la API de Auth0
  }
}
Problema: La validación del token falla con un error de emisor.Solución: Verifica que tu dominio sea correcto y que no incluya https://. La biblioteca construye automáticamente la autoridad como https://{Domain}.
{
  "Auth0": {
    "Domain": "your-tenant.auth0.com"  // Sin https://
  }
}
Problema: ArgumentNullException: Value cannot be null. (Parameter 'Domain') o similar.Solución: Asegúrate de que appsettings.json contenga la sección de Auth0 con los valores de Domain y Audience. Comprueba que la configuración se esté leyendo correctamente:
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")
    };
});
Problema: Se producen errores de certificado SSL/TLS al ejecutar localmente.Solución: Confía en el certificado de desarrollo:
dotnet dev-certs https --trust
O genera un certificado nuevo:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Problema: La autenticación no funciona a pesar de que la configuración es correcta.Solución: Asegúrate de que el middleware esté en el orden correcto. UseAuthentication() debe ir antes de UseAuthorization():
app.UseAuthentication();  // Debe ir antes de UseAuthorization
app.UseAuthorization();
app.MapControllers();
Problema: Las políticas de autorización basadas en alcances siempre fallan.Solución: Asegúrate de que tu token de acceso incluya los alcances requeridos. Al solicitar un token, especifica los alcances:
curl --request POST \
  --url https://YOUR_DOMAIN/oauth/token \
  --data '{"client_id":"...","client_secret":"...","audience":"...","grant_type":"client_credentials","scope":"read:messages write:messages"}'
Verifica también que los alcances estén definidos en la configuración de tu API de Auth0 (Dashboard → APIs → Your API → Permissions).

Aplicación de ejemplo

En el repositorio del SDK hay disponible una aplicación de ejemplo completa que demuestra todas las funcionalidades.

Aplicación de entorno de pruebas

Incluye endpoints públicos y protegidos, compatibilidad con DPoP, integración con Swagger UI y una colección de Postman
Clone y ejecute:
git clone https://github.com/auth0/aspnetcore-api.git
cd aspnetcore-api/Auth0.AspNetCore.Authentication.Api.Playground
# Actualiza appsettings.json con tu configuración de Auth0
dotnet run