尝试使用 jose-jwt 签署 JWT 令牌,但由于某种原因,我很难理解为什么它没有按预期工作。
签名部分正在我的测试中工作,但如果我使用它来请求服务器资源,它会失败。但是,如果我将它粘贴到jwt.io并粘贴我的私钥,当我尝试使用这个新令牌请求服务器资源时,它会完美运行
所以看起来即使它似乎在我的 .net 代码库中工作,它实际上并没有签署令牌。
我写了一些测试,它在签名和验证方面确实有效,没有任何问题。要旨
public class TestUsingJoseJwt
{
public string Identifier { get; set; }
public string Nonce { get; set; }
public JsonNetSerializer JsonNetSerializer { get; set; }
[SetUp]
public void SetupTest()
{
Identifier = Guid.NewGuid().ToString();
Nonce = Guid.NewGuid().ToString();
JsonNetSerializer = new JsonNetSerializer();
}
[Test]
public void CanGenerateSignedJwtUsingJose()
{
// Get the private/ public keys
var privateKeyTexts = File.ReadAllText("FULL PATH TO MY PRIVATE KEY");
var publicKeyTexts = File.ReadAllText("FULL PATH TO MY PUBLIC KEY");
var signedClaim = CreateJwtToken("AAC_1c0b51b0-d673-4872-898e-ce9d6d3f0482", Identifier, Nonce);
var token = CreateToken(signedClaim, privateKeyTexts);
var payload = DecodeToken(token, publicKeyTexts);
var expected = JsonNetSerializer.Serialize(signedClaim);
payload.Should()
.Be(expected, "provided object should be correctly serialized in the token");
}
public static string CreateToken(SignedClaim signedClaim, string privateRsaKey)
{
RSAParameters rsaParams;
using (var tr = new StringReader(privateRsaKey))
{
var pemReader = new PemReader(tr);
var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair;
if (keyPair == null)
{
throw new Exception("Could not read RSA private key");
}
var privateRsaParams = keyPair.Private as RsaPrivateCrtKeyParameters;
rsaParams = DotNetUtilities.ToRSAParameters(privateRsaParams);
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(rsaParams);
//Dictionary<string, object> payload = claims.ToDictionary(k => k.Type, v => (object)v.Value);
var payload = JsonConvert.SerializeObject(signedClaim);
return Jose.JWT.Encode(payload, rsa, JwsAlgorithm.RS256);
}
}
public string DecodeToken(string token, string publicRsaKey)
{
RSAParameters rsaParams;
using (var tr = new StringReader(publicRsaKey))
{
var pemReader = new PemReader(tr);
var publicKeyParams = pemReader.ReadObject() as RsaKeyParameters;
if (publicKeyParams == null)
{
throw new Exception("Could not read RSA public key");
}
rsaParams = DotNetUtilities.ToRSAParameters(publicKeyParams);
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(rsaParams);
// This will throw if the signature is invalid
return Jose.JWT.Decode(token, rsa, JwsAlgorithm.RS256);
}
}
public SignedClaim CreateJwtToken(string consentId, string identifier, string nonce)
{
return new SignedClaim
{
Aud = "https://sandbox.api.endpoint",
Scope = "openid accounts",
Iss = "bdn-8Zpkl9dCbN2tArm2TrgretrtKSexT2XxQ26uL8B",
ResponseType = "code id_token",
RedirectUri = "TEST_REDIRECT_URL",
State = identifier,
Exp = DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds(),
Nonce = nonce,
ClientId = "bdn-8Zpkl9dCbN2tAeerertreterexT2XxQ26uL8B",
Claims = new Claims
{
IdToken = new IdToken
{
Acr = new Acr
{
Essential = true,
Value = "urn:openbanking:psd2:sca",
},
OpenbankingIntentId = new Acr
{
Essential = true,
Value = consentId,
},
},
Userinfo = new Userinfo
{
OpenbankingIntentId = new Acr
{
Value = consentId,
Essential = true,
},
},
},
};
}
}
我几乎处于隧道的尽头,比以往任何时候都感到困惑:(当我在 jwt.io 中手动复制/粘贴私钥但代码无法签署令牌时,任何人都可以解释为什么它可以工作请?
这是一个示例令牌请求
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3NhbmRib3guYXBpLmJhcmNsYXlzIiwic2NvcGUiOiJvcGVuaWQgYWNjb3VudHMiLCJpc3MiOiJiZG4tOFpwa2w5ZENiTjJ0QXJtMlRrZGVzSG1YWUtTZXhUMlh4UTI2dUw4QiIsImNsYWltcyI6eyJpZF90b2tlbiI6eyJhY3IiOnsidmFsdWUiOiJ1cm46b3BlbmJhbmtpbmc6cHNkMjpzY2EiLCJlc3NlbnRpYWwiOnRydWV9LCJvcGVuYmFua2luZ19pbnRlbnRfaWQiOnsidmFsdWUiOiJBQUNfMWMwYjUxYjAtZDY3My00ODcyLTg5OGUtY2U5ZDZkM2YwNDgyIiwiZXNzZW50aWFsIjp0cnVlfX0sInVzZXJpbmZvIjp7Im9wZW5iYW5raW5nX2ludGVudF9pZCI6eyJ2YWx1ZSI6IkFBQ18xYzBiNTFiMC1kNjczLTQ4NzItODk4ZS1jZTlkNmQzZjA0ODIiLCJlc3NlbnRpYWwiOnRydWV9fX0sInJlc3BvbnNlX3R5cGUiOiJjb2RlIGlkX3Rva2VuIiwicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9pbnN5bmMudGVzdC9pbnN5bmNXZWIvb2F1dGgvY29uZmlybSIsInN0YXRlIjoiMmYxMGQyN2EtYmE0Zi00YjJhLTlhNmEtOTQ3NTkyZDdhMThkIiwiZXhwIjoxNTc0MjU1MDgwLjAsIm5vbmNlIjoiZjQyZDkyMTUtMDBmMS00MTVmLTg5NGEtNTJiN2RjZjZmY2M2IiwiY2xpZW50X2lkIjoiYmRuLThacGtsOWRDYk4ydEFybTJUa2Rlc0htWFlLU2V4VDJYeFEyNnVMOEIifQ.Uce2-ZcqQk3JAABltywib79UADhh7HoFv2e6pa0q1b_JuZUeaHk0L_7iC__hVY-TCfG5dmjIFWi80ioQ9hM5WeIX2RLRhhjk8s8pjrOmY243gg2_YJNKK9qwVZtHbieY8OI46ZH8CnQhSILAtVVgqXZeXtFPfk4VvW_yJf4DELSoDtB3hSxoMZtjGbnF5JBzNB0fFBpnTzKQ7a3RPsL_rJUc9IbXOgXBoF-OmlAFNu8F4l5gMmrL146WSSytkUBVQQhDxxc0JQHcz3TqbapxcWSuchu0-nGR8cIXimvQKyaWpG0OISUA-4H5dH3GHNbxOBDT7wTKYLzdG5tj_d9beQ