JWT (JSON Web Token) authentication is widely used for securing APIs in modern applications. In this article, we will build a complete authentication system including:
- User Registration
- User Login
- JWT Token Generation
- Authorization
1. Install Required Packages
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.IdentityModel.Tokens
2. Configure JWT in appsettings.json
"Jwt": {
"Key": "ThisIsSuperSecretKey",
"Issuer": "YourApp",
"Audience": "YourAppUsers",
"DurationInMinutes": 60
}
3. Create User Model
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
4. Create Token Service
public class TokenService
{
private readonly IConfiguration _config;
public TokenService(IConfiguration config)
{
_config = config;
}
public string CreateToken(User user)
{
var claims = new[]
{
new Claim(ClaimTypes.Name, user.Username)
};
var key = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(_config["Jwt:Key"])
);
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _config["Jwt:Issuer"],
audience: _config["Jwt:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(
Convert.ToDouble(_config["Jwt:DurationInMinutes"])
),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
5. Configure Authentication in Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])
)
};
});
builder.Services.AddAuthorization();
6. Create Auth Controller
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly TokenService _tokenService;
public AuthController(TokenService tokenService)
{
_tokenService = tokenService;
}
[HttpPost("login")]
public IActionResult Login(User user)
{
// Dummy validation (replace with DB check)
if (user.Username == "admin" && user.Password == "123")
{
var token = _tokenService.CreateToken(user);
return Ok(new { token });
}
return Unauthorized();
}
}
7. Protect API with [Authorize]
[Authorize]
[HttpGet("secure-data")]
public IActionResult GetSecureData()
{
return Ok("This is protected data");
}
8. Add Middleware
app.UseAuthentication();
app.UseAuthorization();
9. Testing with Postman
- Call
/api/auth/login→ get token - Add header:
Authorization: Bearer YOUR_TOKEN
10. Best Practices
- Never store plain passwords → use hashing (BCrypt)
- Keep JWT key secure
- Use HTTPS always
- Set token expiry
π Conclusion
You have now built a complete JWT authentication system in ASP.NET Core. This includes login, token generation, and secure API access.
You can extend this by adding:
- Refresh Tokens
- Role-based Authorization
- Database Integration (EF Core)