我正在尝试使用JWT授权访问zapi以从zephyr(Jira)获取测试详细信息,但是生成的qsh声明不正确,这使得JWT不正确。有没有其他方法可以在C#中创建qsh?
在Postman客户端中尝试使用生成的JWT值进行尝试时,出现错误,指出使用了不正确的qsh值并显示了正确的qsh值。我对JWT生成的显示值(而不是动态qsh创建)进行了硬编码,并且给出了成功的响应。 代码如下:
var canonical_path_t = "GET&" + RELATIVE_PATH_T + QUERY_STRING_T;
var payload = new Dictionary<string, object>()
{
{ "sub", ACCOUNT_ID }, //assign subject
{ "qsh", getQSH(canonical_path_t) }, //assign query string hash
{ "iss", ACCESS_KEY }, //assign issuer
{ "iat", iat }, //assign issue at(in ms)
{ "exp", exp } //assign expiry time(in ms)
};
string token = JWT.JsonWebToken.Encode(payload, SECRET_KEY, JWT.JwtHashAlgorithm.HS256);
client.DefaultRequestHeaders.Add("Authorization", "JWT " + token);
client.DefaultRequestHeaders.Add("zapiAccessKey", ACCESS_KEY);
client.DefaultRequestHeaders.Add("User-Agent", "ZAPI");
//code to generate qsh
static string getQSH(string qstring)
{
System.Security.Cryptography.SHA256Managed crypt = new
System.Security.Cryptography.SHA256Managed();
StringBuilder hash = new StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(qstring), 0, Encoding.UTF8.GetByteCount(qstring));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
答案 0 :(得分:0)
我可以验证您正在使用的getQSH方法应该工作(因为我必须自己与ZAPI进行交互),因此我要检查的第一件事是您的规范路径。确保您的结构正确。例如...
var RELATIVE_PATH = $"/public/rest/api/1.0/executions/search/cycle/{cycle}";
var QUERY_STRING = $"offset={offset}&projectId={project}&versionId={version}";
var canonical_path = "GET&" + RELATIVE_PATH + "&" + QUERY_STRING;
答案 1 :(得分:0)
TL;DR:qsh
是 方法、相对路径和查询参数按字母顺序排序的 sha256 十六进制值。
我也遇到了一些与 Zephyr 的 qsh
参数相关的问题。我是自己用 NodeJS 创建的。似乎主要路径工作正常,但其中一些使用查询参数,他们给我的qsh
不正确。
最后一个原因是 qsh
字段中的查询参数应该按字母顺序排序。它与路径无关,只是正确生成 qsh
的要求。使用 NodeJS 我只在生成 qsh
之前做了这个:
const sortedQueryString = queryString.split("&").sort().join('&');
const canonicalPath = `${method}&${relativePath}&${sortedQueryString}`;
所以,对于你的 C# 实现,我认为它应该是这样的(未经测试):
var sorted_query_string = QUERY_STRING_T.Split("&").Sort().Join("&");
var canonical_path_t = "GET&" + RELATIVE_PATH_T + "&" + sorted_query_string;
...
不要忘记在相对路径和查询参数之间包含 &。不要使用?。