情景:公司项目基于.net4.0,web客户端实现单点登录需要自己解密id_token,对于jwt解密,.net提供了IdentityModel类库,但是4.0中该类库不可用,所以自己实现了解密方法..
使用了类库:链接地址
下面直接贴代码,直接调用DecodeJWT方法就行,参数为id_token,key默认为空字符串"",
代码
public static IDictionary<string, > DecodeJWT(string jwttoken,string key)
{
//从/.well-known/openid-configuration路径获取jwks_uri
var webClient = new WebClient();
var endpoint = "http://localhost:5000/.well-known/openid-configuration";
var json = webClient.DownloadString(endpoint);
J data = JsonConvert.Deserialize <J >(json);
var jwksUri = data["jwks_uri"].ToString();
//从jwks_uri获取keys
json = webClient.DownloadString(jwksUri);
var keys = JsonConvert.Deserialize <CustomJWKs>(json);
//从jwt获取头部kid,并从keys中找到匹配kid的key
string[] tokenParts = jwttoken.Split('.');
byte[] bytes = From 64Url(tokenParts[0]);
string head= Encoding.UTF8.GetString(bytes);
string kid = JsonConvert.Deserialize <J >(head)["kid"].ToString();
var defaultkey=keys.keys.Where(t => t.kid == kid).FirstOrDefault();
if(defaultkey==null)
{
throw new Exception("未找到匹配的kid");
}
//jwt解密
return RS256Decode(jwttoken, key, defaultkey.e, defaultkey.n);
}
public static IDictionary<string, > RS256Decode(string token, string secret, string exponent,string modulus)
{
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
I 64UrlEncoder urlEncoder = new Jwt 64UrlEncoder();
RSAlgorithmFactory rS256Algorithm = new RSAlgorithmFactory(() =>
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(
new RSAParameters()
{
Modulus = From 64Url(modulus),
Exponent = From 64Url(exponent)
});
byte[] rsaBytes = rsa.ExportCspBlob(true);
X509Certificate2 cert = new X509Certificate2(rsaBytes);
return cert;
});
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, rS256Algorithm);
var json = decoder.DecodeTo (token, secret, verify: false);
return json;
}
catch (TokenExpiredException)
{
throw new Exception("token已过期");
//Console.WriteLine("Token has expired");
//return null;
}
catch (SignatureVerificationException)
{
throw new Exception("token验证失败");
//Console.WriteLine("Token has invalid signature");
//return null;
}
}
public static byte[] From 64Url(string 64Url)
{
string padded = 64Url.Length % 4 == 0
? 64Url : 64Url + "====".Substring( 64Url.Length % 4);
string 64 = padded.Replace("_", "/")
.Replace("-", "+");
return Convert.From 64String( 64);
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
继续阅读与本文标签相同的文章
下一篇 :
科学家创造出第一个3D打印的人眼角膜
-
在线PDF加密,你的隐私你做主!
2026-05-18栏目: 教程
-
浅谈物联网用户体验目标的变化
2026-05-18栏目: 教程
-
Linux基础命令---host域名查询工具
2026-05-18栏目: 教程
-
Apache Flink Meetup 北京站,可能有你最想听的技术干货!
2026-05-18栏目: 教程
-
你真的了解RPA吗?
2026-05-18栏目: 教程
