金蝶云星空C#使用JWT获取token(在Newtonsoft.Json 4.0的基础上,实现Newtonsoft.Json 13.0的部分方法)

news/2025/2/2 16:57:13/

一.项目需求:

1.调用外部接口链接,需要使用JWT获取token。
(本次案例使用JWT10.0,底层调用了Newtonsoft.Json13.0的方法)

二.项目难点:

1.金蝶云星空自带的Newtonsoft.Json 4.0版本过低,不能支持JWT所需的Newtonsoft.Json 13.0方法。

三.解决方案:

解释:替换金蝶自带的Newtonsoft.Json是不可能的,金蝶云星空底层的框架是调用了Newtonsoft.Json的方法的,直接替换会导致整个系统无法运行

1.思路:
a.反编译JWT 10.0,Newtonsoft.Json 13.0。
b. 在低版本Newtonsoft.Json的基础上,重写高版本Newtonsoft.Json的方法。
(本次案例是在Newtonsoft.Json4.0的基础上,实现Newtonsoft.Json13.0的部分方法,从而实现JWT获取token)
c.步骤就是visual studio哪里报错,在反编译工具中找到报错的属性或方法,添加到自定义类中

2.使用工具:Visual Studio(开发工具),ILSpy(反编译工具)

3.操作步骤:
a.新增自定义类JsonNetSerializer
b.新增自定义静态类ExpandMethod,里面写支持JsonNetSerializer的属性,方法
c.在Visual Studio 中报错的方法或者属性,在ILSpy工具中找到并粘贴到自定义方法中
d.调试运行,方案通过

4.代码如下:

在Newtonsoft.Json 13.0的条件下,调用JWT获取token。
代码块1:

//返货Token信息public static string JWTEncode(string ucode){var secretKey = AppSettingService.SecretKey;//获取jwt密钥,示例是存放到配置文件if (!String.IsNullOrEmpty(secretKey)){var dic = new Dictionary<string, object>();dic["systemName"] = ucode;//增加用户名到字典var expiredTimeSpan = 1;if (!String.IsNullOrEmpty(AppSettingService.ExpiredTimeSpan)){var timeSpan = AppSettingService.ExpiredTimeSpan;if (System.Text.RegularExpressions.Regex.IsMatch(timeSpan, "^[1-9]\\d*$")){expiredTimeSpan = Convert.ToInt32(timeSpan);}}var jwtcreatedOver =
Math.Round((DateTime.UtcNow.AddMinutes(expiredTimeSpan) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);dic["exp"] = jwtcreatedOver;// 指定token的生命周期。unix时间戳格式IJwtAlgorithm algorithm = new HMACSHA512Algorithm();IJsonSerializer serializer = new JsonNetSerializer();	//在Newtonsoft.Json 4.0的条件下,这个方法报错IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);return encoder.Encode(dic, secretKey);//返回生成的token}elsereturn "";}

在Newtonsoft.Json 4.0的条件下,重写上面案例的JsonNetSerializer方法,调用JWT获取token。
代码块2:
1.自定义静态JsonNetSerializer类:(直接从ILSpy反编译工具中整段复制出来)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;namespace ZJYceshi
{//继承JWT.IJsonSerializer,后面才能进行类型转换public class JsonNetSerializer:JWT.IJsonSerializer{private readonly JsonSerializer _serializer;//ExpandMethod.CreateDefault()为自定义方法,原方法为JsonSerializer.CreateDefault(),属于Newtonsoft.Json 13.0的方法public JsonNetSerializer() : this(ExpandMethod.CreateDefault()){}public JsonNetSerializer(JsonSerializer serializer){if (serializer == null){throw new ArgumentNullException("serializer");}this._serializer = serializer;}public string Serialize(object obj){if (obj == null){throw new ArgumentNullException("obj");}StringBuilder stringBuilder = new StringBuilder();string result;using (StringWriter stringWriter = new StringWriter(stringBuilder)){using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)){this._serializer.Serialize(jsonTextWriter, obj);result = stringBuilder.ToString();}}return result;}public object Deserialize(Type type, string json){if (type == null){throw new ArgumentNullException("type");}if (string.IsNullOrEmpty(json)){throw new ArgumentException("json");}object result;using (StringReader stringReader = new StringReader(json)){using (JsonTextReader jsonTextReader = new JsonTextReader(stringReader)){result = this._serializer.Deserialize(jsonTextReader, type);}}return result;}}
}

2.自定义静态ExpandMethod,将程序所需的Newtonsoft.Json 13.0的方法添加到此类中:

	using System;using System.Collections.Generic;using System.Linq;using System.Runtime.CompilerServices;using System.Text;using System.Threading.Tasks;using Newtonsoft.Json;namespace ZJYceshi{public static class ExpandMethod{public static JsonSerializer CreateDefault(){Func<JsonSerializerSettings> expr_05 = ExpandMethod.DefaultSettings;return JsonSerializer.Create((expr_05 != null) ? expr_05() : null);}[Nullable(new byte[]{2,1})]public static Func<JsonSerializerSettings> DefaultSettings{[return: Nullable(new byte[]{2,1})]get;[param: Nullable(new byte[]{2,1})]set;}[Embedded, AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false), CompilerGenerated]internal sealed class NullableAttribute : Attribute{public readonly byte[] NullableFlags;public NullableAttribute(byte b){this.NullableFlags = new byte[]{b};}public NullableAttribute(byte[] nullableFlags){this.NullableFlags = nullableFlags;}}[Embedded, CompilerGenerated]internal sealed class EmbeddedAttribute : Attribute{}}
}

3.微调JWT获取Token方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;namespace ZJYceshi
{public class ResultToken{public static string JWTEncode(string ucode){var secretKey = AppSettingService.SecretKey;//获取jwt密钥,示例是存放到配置文件if (!String.IsNullOrEmpty(secretKey)){var dic = new Dictionary<string, object>();dic["systemName"] = ucode;//增加用户名到字典var expiredTimeSpan = 1;if (!String.IsNullOrEmpty(AppSettingService.ExpiredTimeSpan)){var timeSpan = AppSettingService.ExpiredTimeSpan;if (System.Text.RegularExpressions.Regex.IsMatch(timeSpan, "^[1-9]\\d*$")){expiredTimeSpan = Convert.ToInt32(timeSpan);}}var jwtcreatedOver =Math.Round((DateTime.UtcNow.AddMinutes(expiredTimeSpan) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);dic["exp"] = jwtcreatedOver;// 指定token的生命周期。unix时间戳格式IJwtAlgorithm algorithm = new HMACSHA512Algorithm();//JsonSerializer serializer = new JsonNetSerializer();//调整语句,将紫定义JsonNetSerializer类,强制转换为JWT10.0的类IJsonSerializer serializer = (IJsonSerializer)(new JsonNetSerializer());IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);return encoder.Encode(dic, secretKey);//返回生成的token}elsereturn "";}}
}

5.方案结果:

1.Newtonsoft.Json 13.0 和 Newtonsoft.Json 4.0 环境下,JWT获取tokn均成功!


http://www.ppmy.cn/news/52993.html

相关文章

【MySQL】存放页面的大池子——InnoDB的表空间

1 前置知识回顾 1.1 页面类型 InnoDB是以页为单位管理存储空间的。我们的聚簇索引&#xff08;也就是完整的表数据&#xff09;和其他的二级索引都是以B树的形式保存到表空间中&#xff0c;而B树中的节点就是数据页&#xff0c;这个数据页的类型名其实是 FIL_PAGE_INDEX。 除…

维度云工业品ERP进销存软件教您如何突破工业品生意的困境?

是困境也是机遇 随着全球化和技术进步的不断推进&#xff0c;工业品贸易正逐渐成为国际贸易的重要组成部分。工业品包含了从原材料、零部件到工业设备、机械以及其他工业用品等范畴的产品&#xff0c;涉及各种制造、加工和组装过程。在全球供应链互联互通之下&#xff0c;工业品…

Python 包的依赖管理方法整理记录

python下载的包或者依赖一直没有关注过&#xff0c;直到卸载时才发现有卸载残留&#xff0c;所以特此整理一番。 Node.js 有 Npm 包管理工具&#xff0c;通过 package.json 配置项目依赖&#xff0c;最多再通过 nvm 来进行环境切换&#xff1b; Java 有 Maven Gradle 来进行包管…

如何利用代码快速生成mapper.xml的<resultMap>

一&#xff0c;问题引入 当我们开发 mapper.xml ---->dao接层 ---->service接口---->serviceImp ---->controller层&#xff0c; 其中在mapper.xml编写查询语句的sql时会遇到sql查询到的结果 涉及到多张表的字段&#xff0c;或者单张表的字段过多时&#xff0c; 这…

【UE】简易的水材质

引擎版本&#xff1a;4.26 效果 步骤 1. 创建一个材质&#xff0c;命名为“M_Water” 2. 打开“M_Water”&#xff0c;将混合模式设为半透明&#xff0c; 光照模式设为表面半透明体积&#xff0c;在这种模式下我们可以使用金属度、粗糙度等接口 3. 创建一个4维常量节点&…

笠翁对韵-喜欢拿走

《笠翁对韵》 清李渔 著 卷上 一 东   天对地&#xff0c;雨对风。大陆对长空。山花对海树&#xff0c;赤日对苍穹。雷隐隐&#xff0c;雾蒙蒙。日下对天中。风高秋月白&#xff0c;雨霁晚霞红。牛女二星河左右&#xff0c;参商两曜斗西东。十月塞边&#xff0c;飒飒寒霜惊…

阿里EGES

EGES&#xff1a;Billion-scale Commodity Embedding for E-commerce Recommendation in Alibaba 阿里的EGES是Graph Embedding的一个经典应用&#xff0c;在内容冷启和物料召回上面有较多的落地潜力。主要思想是根据用户交互的物料作为节点构建物料图&#xff0c;在传统的Dee…

从零入门激光SLAM——总目录与更新情况

第一章 初识 1.1 什么是SLAM 从零入门激光SLAM&#xff08;一&#xff09;——什么是SLAM_桦树无泪的博客-CSDN博客 1.2 什么是Ubuntu 从零入门激光SLAM&#xff08;二&#xff09;——Ubuntu基础_乌班图系统架构_桦树无泪的博客-CSDN博客 1.3 什么是ROS 从零入门激光S…