Tokens JWT en C# (.NET): guía completa para trabajar con System.IdentityModel.Tokens.Jwt
\n\nJSON Web Token (JWT) es un formato compacto y seguro para URL, utilizado para transmitir datos entre partes como un objeto JSON. En el ecosistema de C# (.NET), para trabajar con JWT se utiliza la potente biblioteca System.IdentityModel.Tokens.Jwt, que forma parte del paquete Microsoft.IdentityModel.Tokens. Esta herramienta permite generar, firmar, verificar y decodificar tokens JWT, proporcionando autenticación segura e intercambio de datos en aplicaciones web, API y microservicios.
\n\nInstalación de la biblioteca
\nPara comenzar, agregue el paquete NuGet al proyecto. Ejecute el comando en la consola del administrador de paquetes:
\ndotnet add package System.IdentityModel.Tokens.Jwt\nO a través de la Consola del Administrador de Paquetes en Visual Studio:
\nInstall-Package System.IdentityModel.Tokens.Jwt\n\nComponentes principales de la biblioteca
\n- \n
JwtSecurityTokenHandler— clase principal para crear, serializar y verificar tokens. \n SecurityTokenDescriptor— descripción del token: claims, tiempo de vida, firma. \n SymmetricSecurityKey— clave simétrica para la firma (HS256, HS384, HS512). \n SigningCredentials— credenciales de firma (algoritmo + clave). \n TokenValidationParameters— parámetros de validación (verificación de firma, tiempo de vida, emisor). \n
Generación de un token JWT en C#
\nCreemos un token simple con claims (declaraciones) personalizadas y un tiempo de vida de 1 hora:
\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Security.Claims;\nusing System.Text;\nusing Microsoft.IdentityModel.Tokens;\n\npublic string GenerateToken()\n{\n var secretKey = "my_super_secret_key_1234567890!";\n var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));\n var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);\n\n var claims = new[]\n {\n new Claim(ClaimTypes.Name, "Iván Petrov"),\n new Claim(ClaimTypes.Email, "ivan@example.com"),\n new Claim(ClaimTypes.Role, "Admin")\n };\n\n var tokenDescriptor = new SecurityTokenDescriptor\n {\n Subject = new ClaimsIdentity(claims),\n Expires = DateTime.UtcNow.AddHours(1),\n Issuer = "MyApp",\n Audience = "MyAppUsers",\n SigningCredentials = credentials\n };\n\n var tokenHandler = new JwtSecurityTokenHandler();\n var token = tokenHandler.CreateToken(tokenDescriptor);\n return tokenHandler.WriteToken(token);\n}\n\nVerificación de un token JWT
\nAl recibir un token del cliente, es necesario verificar su firma, fecha de caducidad y otros parámetros:
\npublic ClaimsPrincipal ValidateToken(string token)\n{\n var secretKey = "my_super_secret_key_1234567890!";\n var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));\n\n var tokenHandler = new JwtSecurityTokenHandler();\n var validationParameters = new TokenValidationParameters\n {\n ValidateIssuer = true,\n ValidIssuer = "MyApp",\n ValidateAudience = true,\n ValidAudience = "MyAppUsers",\n ValidateLifetime = true,\n IssuerSigningKey = key,\n ClockSkew = TimeSpan.Zero // elimina el margen de tiempo por defecto\n };\n\n try\n {\n var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);\n return principal;\n }\n catch (SecurityTokenExpiredException)\n {\n Console.WriteLine("El token ha caducado");\n return null;\n }\n catch (SecurityTokenInvalidSignatureException)\n {\n Console.WriteLine("Firma del token no válida");\n return null;\n }\n}\n\nDecodificación del token sin verificar la firma
\nA veces es necesario simplemente leer