Welcome to our comprehensive guide on generating JSON Web Tokens (JWT) in ASP .NET! By the end of this lesson, you'll be able to implement JWT for authentication in your own projects. Let's dive right in!
š” Pro Tip: JWT is a compact, URL-safe means of representing claims to enable authentication. It's widely used in modern web applications for secure transfer of data between parties.
šÆ Key Concept: Claims are pieces of information encoded in a JWT, such as user identity, roles, or expiration time.
A JWT typically consists of three parts: header, payload, and signature. The header and payload are separated by a dot (.), and the header, payload, and signature are joined together by another dot to form the complete JWT.
Header.Payload.SignatureLet's start by creating a new ASP .NET Core Web API project using the dotnet new webapi command.
dotnet new webapi -n JwtDemo
cd JwtDemoWe'll need to install the Microsoft.AspNetCore.Authentication.JwtBearer and Microsoft.Extensions.SecretManager.Json packages via NuGet.
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.Extensions.SecretManager.JsonNext, we'll configure JWT in the Startup.cs file.
š Note: We'll define a JwtOptions class to store our JWT configuration settings.
public class JwtOptions
{
public string Issuer { get; set; }
public string Audience { get; set; }
public string SecretKey { get; set; }
public int Expiration { get; set; }
}š Note: In the ConfigureServices method, we'll add services for JWT token validation and configure the JWT authentication middleware.
public void ConfigureServices(IServiceCollection services)
{
var jwtOptions = new JwtOptions
{
Issuer = "CodeYourCraft",
Audience = "CodeYourCraft",
SecretKey = "YourSecretKey",
Expiration = 3600 // Token expiration in seconds (1 hour)
};
services.AddSingleton<IJwtOptions>(jwtOptions);
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecretKey))
};
});
services.AddControllers();
}š Note: In the Configure method, we'll add the authentication middleware.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}š Note: We'll create a simple API controller with a protected action requiring authentication.
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Json(new[] {
new { temperature = Random.Shared.Next(1, 100), summary = "Sample weather data" }
});
}
}š Note: We'll create a UserService to generate JWT tokens.
public class UserService
{
private readonly IJwtOptions _jwtOptions;
public UserService(IJwtOptions jwtOptions)
{
_jwtOptions = jwtOptions;
}
public string GenerateToken(string username)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var signingCredentials = new SigningCredentials(_jwtOptions.SecretKey, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
expires: DateTime.UtcNow.AddHours(_jwtOptions.Expiration),
signingCredentials: signingCredentials);
var encodedJwt = new JwtEncoder(signingCredentials).Encode(jwt);
return encodedJwt;
}
}š Note: We'll inject the UserService and use it to authenticate and generate a JWT token for API requests.
[ApiController]
[Route("[controller]")]
public class AuthenticateController : ControllerBase
{
private readonly UserService _userService;
public AuthenticateController(UserService userService)
{
_userService = userService;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel loginModel)
{
if (loginModel.Username != "testuser" || loginModel.Password != "testpassword")
{
return BadRequest("Invalid username or password.");
}
var token = _userService.GenerateToken(loginModel.Username);
return Ok(new { token = token });
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}Now you have a functional ASP .NET Core Web API project that can generate JWT tokens for authentication. You can test the /Authenticate/login endpoint with a simple HTTP client to retrieve a JWT token, which can be sent in the Authorization header (Bearer <token>) for protected API requests.
Which package provides the `JwtSecurityToken` class in ASP .NET Core?