.Net中使用JWT
一、JWT数据结构
实际的 JWT 大概就像下面这样。
它是一个很长的字符串,中间用点(.)分隔成三个部分。注意,JWT 内部是没有换行的,这里只是为了便于展示,将它写成了几行。
JWT 的三个部分依次如下。
Header(头部包含算法信息)
Payload(负载包含实际传递信息)
Signature(对前面两部分的签名)
写成一行,就是下面这样
二、怎么生成JWT
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
//payload部分
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("zidingyi", "自定义"));
claims.Add(new Claim(ClaimTypes.NameIdentifier, "11111"));
claims.Add(new Claim(ClaimTypes.Name, "zebary"));
claims.Add(new Claim(ClaimTypes.Role, "admin"));
claims.Add(new Claim(ClaimTypes.Role, "user"));
//服务器私钥不能太短
string key = "dkdls()dlfj%sldfj#sdlfnbmlkepkkqaopxd@9094";
//超时时间
DateTime expire = DateTime.Now.AddHours(1);
//编码
byte[] secBytes = Encoding.UTF8.GetBytes(key);
var secKey = new SymmetricSecurityKey(secBytes);
var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials);
string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
注意JWT中payload是明文保存的,不要把不能被客户端知道的信息放到JWT中
我们可以做个测试,对编码之后的jwt不用私钥直接解码
//不使用私钥,直接解码
string[] segments = jwt.Split('.');
string head = JwtDecode(segments[0]);
string payload = JwtDecode(segments[1]);
Console.WriteLine($"head:{head}");
Console.WriteLine($"payload:{payload}");
string JwtDecode(string s)
{
s = s.Replace('-', '+').Replace('_', '/');
switch (s.Length % 4)
{
case 2:
s += "==";
break;
case 3:
s += "=";
break;
}
var bytes = Convert.FromBase64String(s);
return Encoding.UTF8.GetString(bytes);
}
使用私钥验证是否篡改
//使用私钥验证签名是否篡改
string seckey = "dkdls()dlfj%sldfj#sdlfnbmlkepkkqaopxd@9094";
JwtSecurityTokenHandler tokenHandler = new();
TokenValidationParameters valParams = new();
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(seckey));
valParams.IssuerSigningKey = securityKey;
valParams.ValidateIssuer = false;
valParams.ValidateAudience = false;
//验证是否篡改,如果篡改会报异常
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,valParams,out SecurityToken secToken);
foreach(var claim in claimsPrincipal.Claims)
{
Console.WriteLine($"{claim.Type}={claim.Value}");
}
标签:string,使用,JWT,claims,var,new,Net From: https://www.cnblogs.com/zebrafish/p/17134306.html以上代码在.Net 6 和.Net Framework 4.6中运行过其他没有试过