JWT tokens in C# (.NET): complete guide to working with System.IdentityModel.Tokens.Jwt
JSON Web Token (JWT) is a compact, URL-safe format for transmitting data between parties as a JSON object. In the C# (.NET) ecosystem, the powerful System.IdentityModel.Tokens.Jwt library, which is part of the Microsoft.IdentityModel.Tokens package, is used for working with JWT. This tool allows you to generate, sign, validate, and decode JWT tokens, ensuring secure authentication and data exchange in web applications, APIs, and microservices.
Installing the library
To get started, add the NuGet package to your project. Run the command in the package manager console:
dotnet add package System.IdentityModel.Tokens.JwtOr via the Package Manager Console in Visual Studio:
Install-Package System.IdentityModel.Tokens.JwtMain components of the library
JwtSecurityTokenHandler— the main class for creating, serializing, and validating tokens.SecurityTokenDescriptor— token description: claims, lifetime, signature.SymmetricSecurityKey— symmetric key for signing (HS256, HS384, HS512).SigningCredentials— signing credentials (algorithm + key).TokenValidationParameters— validation parameters (signature verification, lifetime, issuer).
Generating a JWT token in C#
Let's create a simple token with custom claims and a lifetime of 1 hour:
using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Text;using Microsoft.IdentityModel.Tokens;
public string GenerateToken(){ var secretKey = "my_super_secret_key_1234567890!"; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[] { new Claim(ClaimTypes.Name, "Ivan Petrov"), new Claim(ClaimTypes.Email, "ivan@example.com"), new Claim(ClaimTypes.Role, "Admin") };
var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddHours(1), Issuer = "MyApp", Audience = "MyAppUsers", SigningCredentials = credentials };
var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token);}Validating (verifying) a JWT token
When receiving a token from a client, it is necessary to verify its signature, expiration, and other parameters:
public ClaimsPrincipal ValidateToken(string token){ var secretKey = "my_super_secret_key_1234567890!"; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var tokenHandler = new JwtSecurityTokenHandler(); var validationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "MyApp", ValidateAudience = true, ValidAudience = "MyAppUsers", ValidateLifetime = true, IssuerSigningKey = key, ClockSkew = TimeSpan.Zero // remove default time margin };
try { var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken); return principal; } catch (SecurityTokenExpiredException) { Console.WriteLine("Token expired"); return null; } catch (SecurityTokenInvalidSignatureException) {
Console.WriteLine("Invalid token signature"); return null; }}Decoding a token without signature validation
Sometimes you just need to read