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

# API web de ASP.NET Core

> Agrega la autenticación JWT de Auth0 a una API web de ASP.NET Core con endpoints protegidos

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Callout icon="pencil" color="#FFC107" iconType="solid">
  Esta guía de inicio rápido está actualmente en **Beta**. ¡Nos encantaría conocer sus comentarios!
</Callout>

<Accordion title="Usa IA para integrar Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  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](https://agentskills.io/home).

  **Instalar:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-aspnetcore-api
  ```

  **Luego, pídale a su asistente de IA:**

  ```text theme={null}
  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 →](/es/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **Requisitos previos:** Antes de comenzar, asegúrese de tener instalado lo siguiente:

  * **[SDK de .NET 8.0](https://dotnet.microsoft.com/download/dotnet/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.
</Note>

<div id="get-started">
  ## Primeros pasos
</div>

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.

<Steps>
  <Step title="Crear un nuevo proyecto" stepNumber={1}>
    Cree un nuevo proyecto de API web de ASP.NET Core para esta guía de inicio rápido

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

    Abrir el proyecto

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

  <Step title="Instala el SDK de Auth0" stepNumber={2}>
    ```bash theme={null}
    dotnet add package Auth0.AspNetCore.Authentication.Api
    ```
  </Step>

  <Step title="Configura tu API de Auth0" stepNumber={3}>
    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:

    <Tabs>
      <Tab title="CLI">
        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`:

        <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 updated with your Auth0 API details:" && \
            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 updated with your Auth0 API details:"
            Get-Content appsettings.json
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Dashboard">
        Antes de comenzar, agregue la configuración de Auth0 a su archivo `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. Ve a [Auth0 Dashboard](https://manage.auth0.com) → **Applications** → **APIs**
        2. Haz clic en **Create API**
        3. Introduce los datos de tu API:
           * **Nombre**: My ASP.NET Core API
           * **Identifier**: `https://my-api` (esta será tu Audiencia)
           * **Signing Algorithm**: RS256
        4. Haz clic en **Create**
        5. Reemplaza `YOUR_AUTH0_DOMAIN` en `appsettings.json` por tu **dominio** de la pestaña Test (por ejemplo, `your-tenant.auth0.com`)
        6. Reemplaza `YOUR_AUTH0_API_IDENTIFIER` en `appsettings.json` por tu **Identifier** (por ejemplo, `https://my-api`)

        <Info>
          Tu **dominio** no debe incluir `https://`; usa solo el nombre de dominio (por ejemplo, `your-tenant.auth0.com`).

          La **Audiencia** (identificador de API) es un identificador único para tu API y puede ser cualquier URI válida. No tiene que ser una URL de acceso público.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurar la autenticación" stepNumber={4}>
    Reemplace todo el contenido de `Program.cs` con el siguiente código:

    ```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="Crear endpoints públicos y protegidos" stepNumber={5}>
    Agregue endpoints para probar la autenticación. Agregue el siguiente código a `Program.cs` antes de `app.Run()`:

    ```csharp Program.cs theme={null}
    // 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");
    ```
  </Step>

  <Step title="Inicie la API" stepNumber={6}>
    ```bash theme={null}
    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).
  </Step>
</Steps>

<Check>
  **Punto de verificación**

  Ahora deberías tener una API protegida por Auth0 totalmente funcional ejecutándose en tu [localhost](https://localhost:7190/)
</Check>

***

<div id="advanced-usage">
  ## Uso avanzado
</div>

<Accordion title="Llamar a APIs protegidas">
  Prueba tus endpoints protegidos con un token de acceso.

  **1. Obtén un token de acceso** de Auth0 mediante el flujo 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>
    Para obtener `YOUR_CLIENT_ID` y `YOUR_CLIENT_SECRET`, crea una aplicación de máquina a máquina en el [Auth0 Dashboard](https://manage.auth0.com/#/applications) y autorízala para tu API.
  </Info>

  **2. Prueba el endpoint público** (debe devolver 200 OK):

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

  **3. Prueba el endpoint protegido sin autenticación** (debe devolver 401 Unauthorized):

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

  **4. Llama al endpoint protegido con el token:**

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

<Accordion title="Usar endpoints basados en controladores">
  Para APIs más grandes, usa controladores en lugar de endpoints de Minimal APIs.

  **1. Agrega compatibilidad con controladores:**

  ```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. Crea un controlador:**

  Crea `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="Proteger rutas con autorización basada en alcances">
  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](https://manage.auth0.com) → APIs → Tu API → Permissions, agrega los alcances:

  * `read:messages` - Leer mensajes
  * `write:messages` - Escribir mensajes

  **2. Configura políticas de autorización:**

  ```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. Aplica las políticas a los endpoints:**

  ```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");
  ```

  Al solicitar un token de acceso, incluye el scope requerido:

  ```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="Uso de DPoP para reforzar la seguridad">
  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:**

  ```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();  // Habilita DPoP con la configuración predeterminada
  ```

  **Modos de DPoP:**

  Acepte tokens DPoP y Bearer (predeterminado):

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

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

  Acepte solo tokens DPoP y rechace los tokens Bearer:

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

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

  Configure los parámetros de validación de tiempo:

  ```csharp theme={null}
  .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
  });
  ```

  <Info>
    Obtenga más información sobre DPoP en la [documentación de DPoP de Auth0](https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop).
  </Info>
</Accordion>

<Accordion title="Implementación de políticas de autorización personalizadas">
  Cree políticas de autorización reutilizables para requisitos complejos.

  **1. Cree un requisito personalizado:**

  ```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. Cree un manejador:**

  ```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. Registre y use la política:**

  ```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();
  // ... resto de la configuración
  ```
</Accordion>

<Accordion title="Acceso a la información del usuario">
  Extraiga la información del usuario del token autenticado.

  ```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="Validación personalizada de tokens">
  Personalice los parámetros de validación del token JWT para requisitos específicos.

  ```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">
  ## Recursos adicionales
</div>

<CardGroup cols={3}>
  <Card title="Documentación del SDK" icon="book" href="https://github.com/auth0/aspnetcore-api">
    Documentación completa del SDK y referencia de la API
  </Card>

  <Card title="Guía de migración" icon="arrow-right-arrow-left" href="https://github.com/auth0/aspnetcore-api/blob/master/MIGRATION.md">
    Migre desde la autenticación con JWT Bearer
  </Card>

  <Card title="Ejemplos de código" icon="code" href="https://github.com/auth0/aspnetcore-api/blob/master/EXAMPLES.md">
    Ejemplos y patrones de código completos
  </Card>

  <Card title="Documentación de DPoP" icon="shield" href="https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop">
    Más información sobre la seguridad con prueba de posesión
  </Card>

  <Card title="Prácticas recomendadas para tokens" icon="key" href="https://auth0.com/docs/secure/tokens/token-best-practices">
    Prácticas recomendadas de seguridad para tokens
  </Card>

  <Card title="Foro de la comunidad" icon="comments" href="https://community.auth0.com/">
    Obtenga ayuda de la comunidad de Auth0
  </Card>
</CardGroup>

***

<div id="common-issues">
  ## Problemas comunes
</div>

<AccordionGroup>
  <Accordion title="401 No autorizado: audiencia no válida">
    **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.

    ```json theme={null}
    {
      "Auth0": {
        "Audience": "https://my-api"  // Debe coincidir con el identificador de la API de Auth0
      }
    }
    ```
  </Accordion>

  <Accordion title="401 No autorizado: emisor no válido">
    **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}`.

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

  <Accordion title="No se encontraron los valores de configuración">
    **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:

    ```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="Errores de certificado HTTPS en desarrollo">
    **Problema:** Se producen errores de certificado SSL/TLS al ejecutar localmente.

    **Solución:** Confía en el certificado de desarrollo:

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

    O genera un certificado nuevo:

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

  <Accordion title="Problemas con el orden del middleware">
    **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()`:

    ```csharp theme={null}
    app.UseAuthentication();  // Debe ir antes de UseAuthorization
    app.UseAuthorization();
    app.MapControllers();
    ```
  </Accordion>

  <Accordion title="Los alcances no funcionan en las políticas de autorización">
    **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:

    ```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"}'
    ```

    Verifica también que los alcances estén definidos en la configuración de tu API de Auth0 (Dashboard → APIs → Your API → Permissions).
  </Accordion>
</AccordionGroup>

***

<div id="sample-application">
  ## Aplicación de ejemplo
</div>

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

<Card title="Aplicación de entorno de pruebas" icon="github" href="https://github.com/auth0/aspnetcore-api/tree/master/Auth0.AspNetCore.Authentication.Api.Playground">
  Incluye endpoints públicos y protegidos, compatibilidad con DPoP, integración con Swagger UI y una colección de Postman
</Card>

Clone y ejecute:

```bash theme={null}
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
```
