Есть ли способ сгенерировать значение qsh для генерации токена JWT для доступа к zephyr api?

Я пытаюсь получить доступ к zapi, чтобы получить данные теста от zephyr (Jira) с использованием авторизации JWT. Но сгенерированное утверждение qsh неверно, что делает JWT неверным. Есть ли альтернативный метод создания qsh на С#?

При попытке в клиенте Postman с сгенерированным значением JWT выдается ошибка, что используется неправильное значение qsh, и отображается правильное значение qsh. Я жестко закодировал отображаемое значение (вместо динамического создания qsh) для генерации JWT, и это дает успешный ответ. Код приведен ниже:

    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();
    }

person Ash G    schedule 16.05.2019    source источник


Ответы (2)


я могу убедиться, что метод 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;
person Tyler Jones    schedule 02.10.2019

TL;DR: qsh – это sha256 шестнадцатеричное значение метода, относительного пути и параметров запроса, отсортированных по алфавиту.

У меня также были проблемы с параметром qsh для Zephyr. Я создавал сам с помощью NodeJS. Кажется, что большинство путей работали правильно, но некоторые из них, использующие параметр запроса, выдавали мне qsh неверно.

Последняя причина заключается в том, что параметры запроса в поле qsh должны быть отсортированы по алфавиту. Это не связано с путем, это просто требование для правильного создания qsh. С NodeJS я сделал только это перед созданием qsh:

const sortedQueryString = queryString.split("&").sort().join('&');
const canonicalPath = `${method}&${relativePath}&${sortedQueryString}`;

Итак, для вашей реализации на С# я предположил, что это должно быть что-то вроде этого (не проверено):

var sorted_query_string = QUERY_STRING_T.Split("&").Sort().Join("&");
var canonical_path_t = "GET&" + RELATIVE_PATH_T + "&" + sorted_query_string;
...

Не забудьте указать & между относительным путем и параметрами запроса. Не используйте ?.

person SnakeDrak    schedule 05.02.2021