---
title: "Add JWT Authentication to Your ASP.NET Core API"
description: "Secure your ASP.NET Core API using JWT authentication with JWKS."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/csharp/aspnetcore/jwt-backend"
framework: "ASP.NET Core"
language: "C#"
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your ASP.NET Core API

Secure your ASP.NET Core API using JWT authentication with JWKS.

## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your ASP.NET Core backend can verify — no long-lived API keys touch your origin.

## ASP.NET Core Backend Code

```csharp
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Threading.Tasks;

var builder = WebApplication.CreateBuilder(args);

// Set up HttpClient for fetching JWKS
var jwtIssuer = "https://my-api-a32f34.zuplo.api/__zuplo";
var jwksUri = $"{jwtIssuer}/.well-known/jwks.json";
HttpClient httpClient = new();

// Configure JWT Bearer authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = jwtIssuer;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = jwtIssuer,
            ValidAudience = "your-audience",
            RequireSignedTokens = true,
            ValidateIssuerSigningKey = true
        };

        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];

                // If the request is for Hub then retrieve access token from the query string
                var path = context.HttpContext.Request.Path;
                if (!string.IsNullOrEmpty(accessToken) &&
                    path.StartsWithSegments("/protected"))
                {
                    context.Token = accessToken;
                }
                return Task.CompletedTask;
            },
            OnAuthenticationFailed = context =>
            {
                context.NoResult();
                context.Response.StatusCode = 401;
                context.Response.ContentType = "application/json";
                return context.Response.WriteAsync(new
                {
                    error = "Invalid token",
                    details = context.Exception.Message
                }.ToString());
            }
        };
    });

var app = builder.Build();

// Configure the HTTP request pipeline
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/protected", (HttpContext context) =>
{
    var user = context.User.Identity.IsAuthenticated
        ? $"User: {context.User.Identity.Name}"
        : "Unauthorized Access";
    return $"Access granted. {user}";
}).RequireAuthorization();

app.Run();
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
