Unable to use multiple query string parameters while using JWT

Hi I am using JWT authentication to connect jira rest api.
https://xxx.atlassian.net/rest/api/2/issue/68658?overrideScreenSecurity=true&notifyUsers=false is not working whereas

https://xxx.atlassian.net/rest/api/2/issue/68658?overrideScreenSecurity=true

Whenever I include 2 query strings in url . It is throwing 401 exception. Could some one help me how to pass multiple query string parameters while using query string hash?

Hi, @sbonagiri.

To have a better context as to how you are invoking the endpoint, do you mind sharing code snippets of what you tried?

Thanks,
Ian

Hi @iragudo, Below are code snippets I am using
putData(ConfigurationManager.AppSettings[“JiraBaseUrl”], “/rest/api/2/issue/” + 68658, “overrideScreenSecurity=true&notifyUsers=false”, customValue);

public void putData(string baseUrl, string apiPath, string queryString, string data)
{
string token = generatePayLoad(“PUT”, baseUrl, apiPath, queryString);
var stringContent = new StringContent(data, Encoding.UTF8, “application/json”);
using (var httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) })
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));
httpClient.DefaultRequestHeaders.TryAddWithoutValidation(“Authorization”, "JWT " + token);

            using (var response = httpClient.PutAsync(apiPath + "?" + queryString, stringContent).Result)
            {
                string resp = response.Content.ReadAsStringAsync().Result;
            }
        }
    }

public string generatePayLoad(string method,string baseUrl, string apiPath,string queryString)
{
var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long issuedAt = (long)Math.Round((DateTime.UtcNow - unixEpoch).TotalSeconds);
long expiresAt = issuedAt + 3600L;
string canonical_request = method + “&” + apiPath + “&” + queryString;
string signed_canonical_requestByte = getQSH(canonical_request);
var payload = new Dictionary<string, object>()
{
{ “qsh”, signed_canonical_requestByte},
{ “iss”, “com.FactSet.JIRAIntegrations” },
{ “iat”, issuedAt },
{ “exp”, expiresAt },

            };
        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
        IJsonSerializer serializer = new JsonNetSerializer();
        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
        return encoder.Encode(payload, jwtToken);
    }
    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));
        foreach (byte theByte in crypto)
        {
            hash.Append(theByte.ToString("x2"));
        }
        return hash.ToString();
    }

Let me know if I need to provide any other info

Hello @sbonagiri , have you tried URL encoding the query string? Based on this document “Creating a query string hash” part, it says that query strings should be percent encoded. This makes sense since you only encounter the error when you include 2 query strings in the URL, which means you introduce ‘&’ in the query string.

Kindly try it out. Thanks!
Ian

@iragudo I tried following one as well
apiHelper.putData(ConfigurationManager.AppSettings[“JiraBaseUrl”], “/rest/api/2/issue/” + 68658, “overrideScreenSecurity=true%26notifyUsers=false”, customValue);

but this one also failed. Do you think if I need to try something else?

I think we forgot this rule/step in computing the canonical query string

Sort the parameters primarily by their percent-encoded names and secondarily by their percent-encoded values.

Kindly try “notifyUsers=false%26overrideScreenSecurity=true” instead.

2 Likes

That’s awesome… It fixed issue even though I didnt encode &. Thank you som much @iragudo

You’re welcome @sbonagiri . Glad you made it work. In order to guide other community member/s who might experience the same problem, kindly mark the answer that solves the issue.

Have an awesome day :slight_smile: