我正在尝试使用Azure keyvault客户端验证签名,但是它始终返回false。
我设法使用KeyVaultClient.SignAsync方法对其进行签名,但是,当尝试使用KeyVaultClient.VerifyAsync时,结果总是返回false。
// Added for completeness, this method seems to be working correctly
private static async Task<string> SignJwt(KeyVaultClient client)
{
var claimsToSign = new[]
{
new Claim("sub", "UserId123"),
new Claim("custom", "MyValue")
};
var token = new JwtSecurityToken(
issuer: "AuthApp",
audience: "Consumer",
claims: claimsToSign
);
var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary<string, string>()
{
{JwtHeaderParameterNames.Alg, JsonWebKeySignatureAlgorithm.ES256},
{JwtHeaderParameterNames.Typ, "JWT"}
}));
var byteData = Encoding.UTF8.GetBytes(header + "." + token.EncodedPayload);
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var signature = await client.SignAsync(KeyVaultBaseUrl, KeyName, KeyVersion, JsonWebKeySignatureAlgorithm.ES256, digest);
var fullJwt = $"{header}.{token.EncodedPayload}.{Base64UrlEncoder.Encode(signature.Result)}";
return fullJwt;
}
// This always returns a false result
private static async Task<KeyVerifyResult> ValidateJwt()
{
// Example of a JWT produced by the SignJwt method
var jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJVc2VySWQxMjMiLCJjdXN0b20iOiJNeVZhbHVlIiwiaXNzIjoiQXV0aEFwcCIsImF1ZCI6IkNvbnN1bWVyIn0.6tYkBcoFojJVJBhdNST49v4A3VWC1Rqizx_FzmSRICQubDEfXVopfP7Rs9tOBi9YzTCbod9o3hmHzIxANoIh7A";
var client = new KeyVaultClient(GetAccessTokenAsync, new HttpClient());
var jwtParts = jwt.Split('.');
var header = jwtParts[0];
var body = jwtParts[1];
var signature = Encoding.UTF8.GetBytes(Base64UrlEncoder.Decode(jwtParts[2]));
var byteData = Encoding.UTF8.GetBytes($"{header}.{body}");
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var verified = await client.VerifyAsync(KeyVaultBaseUrl, KeyName, KeyVersion, JsonWebKeySignatureAlgorithm.ES256, digest, signature);
return verified;
}
private static async Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
{
var appCredentials = new ClientCredential(ClientId, ClientSecret);
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
var result = await context.AcquireTokenAsync(resource, appCredentials);
return result.AccessToken;
}
有什么想法为什么ValidateJwt总是返回false而不是true?
答案 0 :(得分:0)
解决了。
对于感兴趣的任何人,我都没有正确地使用SignJwt方法对签名进行64位编码:
使用Base64UrlEncoder.Encode/Decode
代替使用Convert.ToBase64String/FromBase64String