0

I'm translating a javascript code that works to a C# (Xamarin application). And I getback from the server 400 'Bad Request'

I would like to know if the code I wrote in C# is correct or I missing something.

JS code:

function requestTokens(code) {
    var codeVerifier = document.getElementById("codeVerifierValue").innerHTML;
    var data = {
        "grant_type": "authorization_code",
        "client_id": "clientid",
        "code": code,
        "code_verifier": codeVerifier,
        "redirect_uri": "https://redirectUrl"
    };
    $.ajax({
        beforeSend: function (request) {
            request.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        },
        url: "https://myUrl",
        data: data,
        success: responseFromPostRequest,
        dataType: "json"
    });
}

C# code:

private HttpClient _httpClient = new HttpClient();

private async Task<string> HttpPost(string url, DataDto data)
{
    var jsonData = JsonConvert.SerializeObject(data);
    var content = new StringContent(jsonData, Encoding.UTF8, "application/x-www-form-urlencoded");

    var response = await _httpClient.PostAsync(new Uri(url), content);
}

Thanks for your help

Updated for log response:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Cache-Control: no-store
  Connection: keep-alive
  Date: Wed, 10 Nov 2021 17:37:43 GMT
  Pragma: no-cache
  Referrer-Policy: no-referrer
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-Android-Received-Millis: 1636565866035
  X-Android-Response-Source: NETWORK 400
  X-Android-Selected-Protocol: http/1.1
  X-Android-Sent-Millis: 1636565857210
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  X-XSS-Protection: 1; mode=block
  Content-Length: 84
  Content-Type: application/json
}}
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
JBD
  • 568
  • 8
  • 25
  • Have you checked the server logs? Do you have debug access to the server? What is the signature of the server endpoint? – Jason Nov 10 '21 at 17:17
  • On the log I found I see the connection, but the log is not very rich so it doesn't give me back the reason – JBD Nov 10 '21 at 17:27
  • @Jason for you what I wrote in c# is correct? – JBD Nov 10 '21 at 17:33
  • I have no idea. Try capturing the request with wireshark or something and compare the js and the C# to see how they differ – Jason Nov 10 '21 at 17:41
  • https://www.google.com/search?q=keycloak+log+request+site:stackoverflow.com – Jason Nov 10 '21 at 17:43
  • I found some log. I think Content-Type should be application/x-www-form-urlencoded and not application/json. But how to correct this ? – JBD Nov 10 '21 at 17:43
  • https://stackoverflow.com/questions/10679214/how-do-you-set-the-content-type-header-for-an-httpclient-request – Jason Nov 10 '21 at 17:44

1 Answers1

0

So I found out that in the case of Content-type application/x-www-form-urlencoded it should not be a JSON file to be pasted in the post request.

There is the code sniped I found :

public static async Task<TResult> PostFormUrlEncoded<TResult>(string url, IEnumerable<KeyValuePair<string, string>> postData)
{
    using (var httpClient = new HttpClient())
    {
        using (var content = new FormUrlEncodedContent(postData))
        {
            content.Headers.Clear();
            content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            HttpResponseMessage response = await httpClient.PostAsync(url, content);

            return await response.Content.ReadAsAsync<TResult>();
        }
    }
}

With this it works perfectly

JBD
  • 568
  • 8
  • 25