首页 > 其他分享 >JwtToken---Token上下文,负责token的创建和验证

JwtToken---Token上下文,负责token的创建和验证

时间:2023-06-16 14:57:56浏览次数:42  
标签:string success Token --- token var new now payLoad

public class JwtToken
{
/// <summary>
/// 秘钥,可以从配置文件中获取
/// </summary>
public static string securityKey = "GQDstclechenxxxxxxxxojPOXOYg5MbeJ1XT0uxxxxxxvVBrk";

/// <summary>
/// 创建jwttoken,源码自定义
/// </summary>
/// <param name="payLoad"></param>
/// <param name="header"></param>
/// <returns></returns>
public static string CreateToken(Dictionary<string, object> payLoad, int expiresMinute, Dictionary<string, object> header = null)
{
if (header == null)
{
header = new Dictionary<string, object>(new List<KeyValuePair<string, object>>() {
new KeyValuePair<string, object>("alg", "HS256"),
new KeyValuePair<string, object>("typ", "JWT")
});
}
//添加jwt可用时间(应该必须要的)
var now = DateTime.UtcNow;
payLoad["nbf"] = ToUnixEpochDate(now);//可用时间起始
payLoad["exp"] = ToUnixEpochDate(now.Add(TimeSpan.FromMinutes(expiresMinute)));//可用时间结束

var encodedHeader = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header));
var encodedPayload = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payLoad));

var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(securityKey));
var encodedSignature = Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(encodedHeader, ".", encodedPayload))));

var encodedJwt = string.Concat(encodedHeader, ".", encodedPayload, ".", encodedSignature);
return encodedJwt;
}

/// <summary>
/// 创建jwtToken,采用微软内部方法,默认使用HS256加密,如果需要其他加密方式,请更改源码
/// 返回的结果和CreateToken一样
/// </summary>
/// <param name="payLoad"></param>
/// <param name="expiresMinute">有效分钟</param>
/// <returns></returns>
public static string CreateTokenByHandler(Dictionary<string, object> payLoad, int expiresMinute)
{

var now = DateTime.UtcNow;

// Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
// You can add other claims here, if you want:
var claims = new List<Claim>();
foreach (var key in payLoad.Keys)
{
var tempClaim = new Claim(key, payLoad[key]?.ToString());
claims.Add(tempClaim);
}


// Create the JWT and write it to a string
var jwt = new JwtSecurityToken(
issuer: null,
audience: null,
claims: claims,
notBefore: now,
expires: now.Add(TimeSpan.FromMinutes(expiresMinute)),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(securityKey)), SecurityAlgorithms.HmacSha256));
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
return encodedJwt;
}

/// <summary>
/// 验证身份 验证签名的有效性,
/// </summary>
/// <param name="encodeJwt"></param>
/// <param name="validatePayLoad">自定义各类验证; 是否包含那种申明,或者申明的值, </param>
/// 例如:payLoad["aud"]?.ToString() == "roberAuddience";
/// 例如:验证是否过期 等
/// <returns></returns>
public static bool Validate(string encodeJwt, Func<Dictionary<string, object>, bool> validatePayLoad)
{
var success = true;
var jwtArr = encodeJwt.Split('.');
var header = JsonConvert.DeserializeObject<Dictionary<string, object>>(Base64UrlEncoder.Decode(jwtArr[0]));
var payLoad = JsonConvert.DeserializeObject<Dictionary<string, object>>(Base64UrlEncoder.Decode(jwtArr[1]));

var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(securityKey));
//首先验证签名是否正确(必须的)
success = success && string.Equals(jwtArr[2], Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(jwtArr[0], ".", jwtArr[1])))));
if (!success)
{
return success;//签名不正确直接返回
}
//其次验证是否在有效期内(也应该必须)
var now = ToUnixEpochDate(DateTime.UtcNow);
success = success && (now >= long.Parse(payLoad["nbf"].ToString()) && now < long.Parse(payLoad["exp"].ToString()));

//再其次 进行自定义的验证
success = success && validatePayLoad(payLoad);

return success;
}
/// <summary>
/// 获取jwt中的payLoad
/// </summary>
/// <param name="encodeJwt"></param>
/// <returns></returns>
public static Dictionary<string, object> GetPayLoad(string encodeJwt)
{
var jwtArr = encodeJwt.Split('.');
var payLoad = JsonConvert.DeserializeObject<Dictionary<string, object>>(Base64UrlEncoder.Decode(jwtArr[1]));
return payLoad;
}
public static long ToUnixEpochDate(DateTime date) =>
(long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
}

标签:string,success,Token,---,token,var,new,now,payLoad
From: https://www.cnblogs.com/luckyTian/p/17485481.html

相关文章

  • Presto-JDBC使用
    一、简介PrestoConnection并不能提供一个持久的Socket连接,而是创建一个OkHttpClient与Presto按照HTTP1.1协议进行通信,并且PrestoConnection仅保存一些基本信息(catalog、schema等)二、使用方式1、建立连接和传统的JDBC方式类似,建立PrestoConnection”连接“,并且通过unwrap方法将......
  • android studio插件-自己用
    主题theme1.XcodeTheme2.OneDarkTheme翻译1.TranslationAICode1.CodeGeex2.Tabnine代码Code输入1.CheckStyle-IDEA:2.IdeaVim:和linux上vim一样编辑文件......
  • [数据分析与可视化] Python绘制数据地图3-GeoPandas使用要点
    本文主要介绍GeoPandas的使用要点。GeoPandas是一个Python开源项目,旨在提供丰富而简单的地理空间数据处理接口。GeoPandas扩展了Pandas的数据类型,并使用matplotlib进行绘图。GeoPandas官方仓库地址为:GeoPandas。GeoPandas的官方文档地址为:GeoPandas-doc。本文主要参考GeoPandasEx......
  • FLASH-CH32x芯片FLASH读写保护解析
    一、flash的操作流程1、解锁芯片复位后默认会给控制寄存器FLASH_CTRL上锁,这个时候不允许设置FLASH的控制寄存器,从而不能修改FLASH的内容。所以每次对FLASH写入数据前,都需要先给它解锁。2、擦除擦除有几种方式:页擦除(256字节、32K、64K)、标准擦除(4K)、全擦,不同擦除方式擦除flash......
  • git cherry-pick 教程
    场景:部分代码变动(某几个提交),这时可以采用Cherrypick。1拿到代码变动提交的log,切换到代码变动的分支,然后查看log.==>gitcheckout变动分支名gitlog在英文状态下输入q!退出log2切换到自己的分支,输入gitcherry-pickgitlog的哈希值3gitpush提交上去下面......
  • MT6833-MTK6833核心板 5G联发科MTK核心板
    联发科MT6833(天玑700)是一款先进的八核CPU芯片,其中包含两颗主频高达2.2GHz的ArmCortex-A76大核心,为用户提供出色的性能和流畅的使用体验。此外,MT6833还搭载了高性能的LPDDR4X内存,频率高达2133MHz,并支持更快的数据传输速度的UFS2.2存储。天玑700采用先进的7nm工艺制造,相比于传统......
  • 升级OpenSSL OpenSSH --2023年6月15日
    2023年6月15日升级OpenSSLOpenSSH#查看openssh版本命令ssh-V#查看openssl版本命令opensslversion当前版本[root@node01~]#ssh-VOpenSSH_7.4p1,OpenSSL1.0.2k-fips26Jan2017[root@node01~]#opensslversionOpenSSL1.0.2k-fips26Jan2017......
  • Apache Storm教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介ApacheStorm是一个分布式实时大数据处理系统。Storm设计用于在容错和水平可扩展方法中处理大量数据。它是一个流数据框架,具有最高的摄取率。虽然Storm是无状态的,它通过ApacheZooKeeper管理分布式环境和集群状态。它很简单,您可以并行地对实时数据执行各种操作。ApacheS......
  • PPT| 数字化工厂PLM-ERP-CAPP-MES-SCADA-LES介绍(可下载)
    PPT总共有24页,有需要PPT的同学可以关注:智能制造数字化咨询PPT总共有24页,有需要PPT的同学可以关注:智能制造数字化咨询......
  • 消防安全知识答题活动小程序v5.0-支持答题后抽奖
    关于答题抽奖活动小程序的设计思考1.功能设计:作为答题抽奖活动小程序,核心功能应包括答题和抽奖两部分。用户通过答题获取抽奖机会,答题可以设置为多个题目,用户回答正确则获得相应分数。在用户答完问题后,可以立即展示是否获得了抽奖机会。抽奖部分需要有相应的抽奖界面,用户可以点击......