方式1:
引用System.IdentityModel.Tokens.Jwt
static void Main(string[] args) { //引用System.IdentityModel.Tokens.Jwt DateTime utcNow = DateTime.UtcNow; string key = "f47b558d-7654-458c-99f2-13b190ef0199"; SecurityKey securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)); var claims = new List() { new Claim("ID","1"), new Claim("Name","fan") }; JwtSecurityToken jwtToken = new JwtSecurityToken( issuer: "fan", audience: "audi~~!", claims: claims, notBefore: utcNow, expires: utcNow.AddYears(1), signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256) ); //生成token方式1 string token1 = new JwtSecurityTokenHandler().WriteToken(jwtToken); //A Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor that contains details of contents of the token. var tokenDescriptor = new SecurityTokenDescriptor // 创建一个 Token 的原始对象 { Issuer = "fan", Audience = "audi", Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "") }), Expires = DateTime.Now.AddMinutes(60), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)), SecurityAlgorithms.HmacSha256) }; //生成token方式2 var securityToken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor); var token2 = new JwtSecurityTokenHandler().WriteToken(securityToken); //校验token var validateParameter = new TokenValidationParameters() { ValidateLifetime = true, ValidateAudience = true, ValidateIssuer = true, ValidateIssuerSigningKey = true, ValidIssuer = "fan", ValidAudience = "audi~~!", IssuerSigningKey = securityKey, }; //不校验,直接解析token //jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token1); try { //校验并解析token var claimsPrincipal = new JwtSecurityTokenHandler().ValidateToken(token1, validateParameter, out SecurityToken validatedToken);//validatedToken:解密后的对象 var jwtPayload = ((JwtSecurityToken)validatedToken).Payload.SerializeToJson(); //获取payload中的数据 } catch (SecurityTokenExpiredException) { //表示过期 } catch (SecurityTokenException) { //表示token错误 } }
方式2:
引用JWT
////// 创建token /// /// public static string CreateJwtToken(IDictionary<string, object> payload, string secret, IDictionary<string, object> extraHeaders = null) { IJwtAlgorithm algorithm = new HMACSHA256Algorithm(); IJsonSerializer serializer = new JsonNetSerializer(); IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder); var token = encoder.Encode(payload, secret); return token; } /// /// 校验解析token /// /// public static string ValidateJwtToken(string token, string secret) { try { IJsonSerializer serializer = new JsonNetSerializer(); IDateTimeProvider provider = new UtcDateTimeProvider(); IJwtValidator validator = new JwtValidator(serializer, provider); IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); IJwtAlgorithm alg = new HMACSHA256Algorithm(); IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, alg); var json = decoder.Decode(token, secret, true); //校验通过,返回解密后的字符串 return json; } catch (TokenExpiredException) { //表示过期 return "expired"; } catch (SignatureVerificationException) { //表示验证不通过 return "invalid"; } catch (Exception) { return "error"; } } //-------------客户端调用--------------- public static void Main(string[] args) { var sign = "123"; var extraHeaders = new Dictionary<string, object> { { "myName", "limaru" }, }; //过期时间(可以不设置,下面表示签名后 10秒过期) double exp = (DateTime.UtcNow.AddSeconds(10) - new DateTime(1970, 1, 1)).TotalSeconds; var payload = new Dictionary<string, object> { { "userId", "001" }, { "userAccount", "fan" }, { "exp",exp } }; var token = CreateJwtToken(payload, sign, extraHeaders); var text = ValidateJwtToken(token, sign); Console.ReadKey(); }
方式3:
手写jwt算法:
JWT组成 样式:"xxxxxxxxxxxx.xxxxxxxxxxxxx.xxxxxxxxxxxxxxxx"由三部分组成. (1).Header头部:{\"alg\":\"HS256\",\"typ\":\"JWT\"}基本组成,也可以自己添加别的内容,然后对最后的内容进行Base64编码. (2).Payload负载:iss、sub、aud、exp、nbf、iat、jti基本参数,也可以自己添加别的内容,然后对最后的内容进行Base64编码. (3).Signature签名:将Base64后的Header和Payload通过.组合起来,然后利用Hmacsha256+密钥进行加密。 #region Base64编码 2 ///3 /// Base64编码 4 /// 5 /// 待编码的文本字符串 6 /// 编码的文本字符串 7 public string Base64UrlEncode(string text) 8 { 9 var plainTextBytes = Encoding.UTF8.GetBytes(text); 10 var base64 = Convert.ToBase64String(plainTextBytes).Replace('+', '-').Replace('/', '_').TrimEnd('='); 11 return base64; 12 } 13 #endregion 14 15 #region Base64解码 16 /// 17 /// Base64解码 18 /// 19 /// 20 /// 21 22 public string Base64UrlDecode(string base64UrlStr) 23 { 24 base64UrlStr = base64UrlStr.Replace('-', '+').Replace('_', '/'); 25 switch (base64UrlStr.Length % 4) 26 { 27 case 2: 28 base64UrlStr += "=="; 29 break; 30 case 3: 31 base64UrlStr += "="; 32 break; 33 } 34 var bytes = Convert.FromBase64String(base64UrlStr); 35 return Encoding.UTF8.GetString(bytes); 36 } #endregion Base64编码和解码 /// /// 手写JWT算法 /// public bool TestJwt1() { string secretKey = Configuration["SecretKey"]; //1.加密 //1.1 表头的处理 string headerBase64Url = this.Base64UrlEncode("{\"alg\":\"HS256\",\"typ\":\"JWT\"}"); //1.2 PayLoad的处理 var jwtPayLoad = new { expire = DateTime.Now.AddMinutes(15), userId = "00000000001", userAccount = "admin" }; string payloadBase64Url = this.Base64UrlEncode(JsonConvert.SerializeObject(jwtPayLoad)); //1.3 Sign的处理 string sign = $"{headerBase64Url}.{payloadBase64Url}".HMACSHA256(secretKey); //1.4 最终的jwt字符串 string jwtStr = $"{headerBase64Url}.{payloadBase64Url}.{sign}"; //2.校验token是否正确 bool result; //True表示通过,False表示未通过 //2.1. 获取token中的PayLoad中的值,并做过期校验 JwtData myData = JsonConvert.DeserializeObject (this.Base64UrlDecode(jwtStr.Split('.')[1])); //这一步已经获取到了payload中的值,并进行转换了 var nowTime = DateTime.Now; if (nowTime > myData.expire) { //表示token过期,校验未通过 result = false; return result; } else { //2.2 做准确性校验 var items = jwtStr.Split('.'); var oldSign = items[2]; string newSign = $"{items[0]}.{items[1]}".HMACSHA256(secretKey); result = oldSign == newSign; //true表示检验通过,false表示检验未通过 return result; } }
参考:
https://www.cnblogs.com/ye-hcj/articles/8151385.html
https://www.cnblogs.com/yaopengfei/p/12162507.html