C# (.NET) 中的 JWT 令牌:使用 System.IdentityModel.Tokens.Jwt 的完整指南
JSON Web Token (JWT) 是一种紧凑的、URL 安全的格式,用于以 JSON 对象的形式在各方之间传输数据。在 C# (.NET) 生态系统中,用于处理 JWT 的强大库是 System.IdentityModel.Tokens.Jwt,它是 Microsoft.IdentityModel.Tokens 包的一部分。该工具允许您生成、签名、验证和解码 JWT 令牌,从而在 Web 应用程序、API 和微服务中实现安全的身份验证和数据交换。
安装库
首先,将 NuGet 包添加到您的项目中。在包管理器控制台中执行以下命令:
dotnet add package System.IdentityModel.Tokens.Jwt或者通过 Visual Studio 中的 Package Manager Console:
Install-Package System.IdentityModel.Tokens.Jwt库的主要组件
JwtSecurityTokenHandler— 用于创建、序列化和验证令牌的主要类。SecurityTokenDescriptor— 令牌的描述:声明 (claims)、生存时间、签名。SymmetricSecurityKey— 用于签名的对称密钥 (HS256, HS384, HS512)。SigningCredentials— 签名凭据(算法 + 密钥)。TokenValidationParameters— 验证参数(签名验证、生存时间、颁发者验证)。
在 C# 中生成 JWT 令牌
让我们创建一个简单的令牌,包含自定义声明 (claims) 和 1 小时的生存时间:
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, "伊万·彼得罗夫"), 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);}验证 JWT 令牌
从客户端收到令牌后,需要验证其签名、有效期和其他参数:
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 // 移除默认的时间偏差 };
try { var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken); return principal; } catch (SecurityTokenExpiredException) { Console.WriteLine("令牌已过期"); return null; } catch (SecurityTokenInvalidSignatureException) { Console.WriteLine("令牌签名无效"); return null; }}解码令牌而不验证签名
有时只需要读取