# Authentication & Authorization with JWT in ASP.NET Core

Securing your API isn’t optional; it’s essential. In this post, we’ll walk through how to implement **JWT (JSON Web Token)** authentication in ASP.NET Core so your API knows who’s calling, and what they’re allowed to do.

---

## 🔐 What is JWT?

JWT stands for **JSON Web Token**  a compact, URL-safe way of representing claims between two parties.

A JWT looks like this:

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

It’s composed of:
- Header
- Payload (claims)
- Signature

The server issues a token after login, and the client sends it with every request.

---

## 🛠️ Step 1: Install JWT Authentication NuGet Package

```bash
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
```

---

## ⚙️ Step 2: Configure JWT in Program.cs

```csharp
builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "yourapp.com",
            ValidAudience = "yourapp.com",
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes("your-super-secret-key"))
        };
    });

builder.Services.AddAuthorization();

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

Store your secret in `appsettings.json` or a secure vault in production.

---

## 🔑 Step 3: Generate a Token After Login

```csharp
[HttpPost("login")]
public IActionResult Login(UserLoginModel model)
{
    // Fake validation
    if (model.Username != "admin" || model.Password != "password")
        return Unauthorized();

    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.UTF8.GetBytes("your-super-secret-key");

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, model.Username),
            new Claim(ClaimTypes.Role, "Admin")
        }),
        Expires = DateTime.UtcNow.AddHours(1),
        Issuer = "yourapp.com",
        Audience = "yourapp.com",
        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    return Ok(new { token = tokenHandler.WriteToken(token) });
}
```

---

## 🔒 Step 4: Protect Your Endpoints

```csharp
[Authorize]
[HttpGet("secure-data")]
public IActionResult GetSecureData()
{
    return Ok("Only logged-in users can see this");
}
```

Or restrict to specific roles:

```csharp
[Authorize(Roles = "Admin")]
public IActionResult GetAdminOnlyData() => Ok("Admins only");
```

---

## 🧪 Testing in Swagger

To test secured endpoints in Swagger:
1. Add `app.UseAuthentication()` before `UseAuthorization()`
2. Configure Swagger to accept JWT headers (optional)
3. Pass your token via **Bearer Token** in Postman or Swagger UI

---

## ✅ Up Next

Your API is now protected! Up next: how to log, trace, and recover from errors using **Serilog** and global error handling middleware.

➡️ [Error Handling & Logging with Serilog →](./aspnetcore-error-logging)

Security first. Let’s keep shipping 🚀

