基于.net4.0实现IdentityServer4客户端JWT解密
程序员文章站
2023-12-28 18:18:16
情景:公司项目基于.net4.0,web客户端实现单点登录需要自己解密id_token,对于jwt解密,.net提供了identitymodel类库,但是4.0中该类库不可...
情景:公司项目基于.net4.0,web客户端实现单点登录需要自己解密id_token,对于jwt解密,.net提供了identitymodel类库,但是4.0中该类库不可用,所以自己实现了解密方法..
使用了类库:
下面直接贴代码,直接调用decodejwt方法就行,参数为id_token,key默认为空字符串"",
代码
public static idictionary<string, object> 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); jobject metadata = jsonconvert.deserializeobject<jobject>(json); var jwksuri = metadata["jwks_uri"].tostring(); //从jwks_uri获取keys json = webclient.downloadstring(jwksuri); var keys = jsonconvert.deserializeobject<customjwks>(json); //从jwt获取头部kid,并从keys中找到匹配kid的key string[] tokenparts = jwttoken.split('.'); byte[] bytes = frombase64url(tokenparts[0]); string head= encoding.utf8.getstring(bytes); string kid = jsonconvert.deserializeobject<jobject>(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, object> rs256decode(string token, string secret, string exponent,string modulus) { try { ijsonserializer serializer = new jsonnetserializer(); idatetimeprovider provider = new utcdatetimeprovider(); ijwtvalidator validator = new jwtvalidator(serializer, provider); ibase64urlencoder urlencoder = new jwtbase64urlencoder(); rsalgorithmfactory rs256algorithm = new rsalgorithmfactory(() => { rsacryptoserviceprovider rsa = new rsacryptoserviceprovider(); rsa.importparameters( new rsaparameters() { modulus = frombase64url(modulus), exponent = frombase64url(exponent) }); byte[] rsabytes = rsa.exportcspblob(true); x509certificate2 cert = new x509certificate2(rsabytes); return cert; }); ijwtdecoder decoder = new jwtdecoder(serializer, validator, urlencoder, rs256algorithm); var json = decoder.decodetoobject(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[] frombase64url(string base64url) { string padded = base64url.length % 4 == 0 ? base64url : base64url + "====".substring(base64url.length % 4); string base64 = padded.replace("_", "/") .replace("-", "+"); return convert.frombase64string(base64); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。