1

I'm trying to communicate with some server but the Authorization header gets removed when I use a GET request.

My code (please excuse the mess):

public ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> header,
            Dictionary<string, string> query, string method)
{
    var queryBuilder = new StringBuilder("?");
    foreach (var queryPair in query)
    {
        queryBuilder.Append(queryPair.Key + "=" + queryPair.Value + "&");
    }

    var queryString = queryBuilder.ToString();
    queryString = queryString.Substring(0, queryString.Length - 1);

    var request = (HttpWebRequest) WebRequest.Create(new Uri(ApiServer + path + queryString));

    request.Timeout = 5000;
    request.UserAgent = "VSpedSync/DevBuild";
    request.Method = method;

    foreach (var headerPair in header)
    {
        if (headerPair.Key.ToLower().Equals("user-agent")) continue;
        if (headerPair.Key.ToLower().Equals("authorization"))
        {
            request.PreAuthenticate = true;
        }
        request.Headers.Add(headerPair.Key, headerPair.Value);
    }

    Debug.WriteLine("preauth "+request.PreAuthenticate);

    if (!body.Equals(""))
    {
        var stream = request.GetRequestStream();
        var streamWriter = new StreamWriter(stream);

        streamWriter.Write(body);

        streamWriter.Close();
    }

    HttpWebResponse response;
    try
    {
        response = (HttpWebResponse) request.GetResponse();
    }
    catch (WebException ex)
    {
        response = (ex.Response as HttpWebResponse);
        if (response == null)
            throw;
    }

    foreach (string requestHeader in request.Headers)
    {
        Debug.WriteLine(" --> "+requestHeader+": "+request.Headers.Get(requestHeader));
    }

    var statusCode = response.StatusCode;
    var responseHeaders = new Dictionary<string, string>();
    foreach (string headerKey in response.Headers)
    {
        var headerVal = response.Headers.Get(headerKey);
        responseHeaders.Add(headerKey, headerVal);
    }

    var responseBody = "NONE";
    try
    {
        var streamReader = new StreamReader(response.GetResponseStream());
        responseBody = streamReader.ReadToEnd();
    }
    catch (Exception)
    {
        responseBody = "ERROR";
        // ignored
    }

    return new ApiResponse(
        statusCode,
        responseBody,
        !responseBody.Equals("ERROR") && !responseBody.Equals("NONE"),
        responseHeaders
    );
}

This is how I call the method:

var apiResponse = api.MakeApiRequest("auth/check/", "", new Dictionary<string, string>()
{
    {"Authorization", "Bearer " + token.token},
    {"test", "f"}
}, new Dictionary<string, string>(), "GET");

The headers that are sent when I use the GET method:

 --> User-Agent: VSpedSync/DevBuild
 --> test: f
 --> Host: localhost:55445

The headers that are sent when I use the POST method:

 --> User-Agent: VSpedSync/DevBuild
 --> Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 --> test: f
 --> Host: localhost:55445

Am I doing something wrong?

Edit: Seems to be solved. I'm using RestSharp now instead of the normal WebRequest.

2
  • 1
    Why don't you debug and see what different thing happens in get and post? Commented Jan 10, 2020 at 21:36
  • @MdHasanIbrahim What exactly should I debug? I tried to reverse engeneer the code of the WebRequest class but I cant figure out why the header gets removed on GET requests. Commented Jan 10, 2020 at 21:39

2 Answers 2

1

You can try to use the HttpClient instead of the WebRequest. I tried the following and the authorization header stayed in the request after sending it.

const string ApiServer = "https://google.com";
static readonly HttpClient _httpClient = new HttpClient();

static async Task Main()
{
    InitializeClient();

    var headers = new Dictionary<string, string>()
    {
        { "Authorization", "Bearer e45jsh56" },
        { "Test", "test_value" }
    };

    var paramterers = new Dictionary<string, string>()
    {
        { "pageNum", "3" },
        { "pageSize", "100" }
    };

    var response = await MakeApiCallAsync("mypath", "request_body", headers, paramterers, "GET");

    Console.WriteLine($"Status Code: {response.StatusCode}.");
}

static void InitializeClient()
{
    //  Set the base URI
    _httpClient.BaseAddress = new Uri(ApiServer);

    //  Set Timeout to 5 seconds
    _httpClient.Timeout = new TimeSpan(hours: 0, minutes: 0, seconds: 5);

    //  Set the default User Agent
    _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("VSpedSync/DevBuild");
}

static async Task<ApiResponse> MakeApiCallAsync(string path, 
    string body, Dictionary<string, string> headers, 
    Dictionary<string, string> query, string method)
{
    //  Generate query string
    string queryString = '?' + 
        string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));

    //  Create the relative URL
    string relativeUrl = path + queryString;

    //  Create the Http Method object
    HttpMethod httpMethod = new HttpMethod(method);

    //  Create the request object
    HttpRequestMessage request = new HttpRequestMessage(httpMethod, relativeUrl);

    //  Set headers to the request
    foreach (KeyValuePair<string, string> h in headers)
    {
        if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(h.Key, h.Value);
        }
    }

    //  Set the content of the request
    if (!string.IsNullOrEmpty(body))
    {
        request.Content = new StringContent(body);
    }

    //  Send the request
    HttpResponseMessage response = await _httpClient.SendAsync(request);

    //  Display request headers
    foreach(var h in request.Headers)
    {
        Console.WriteLine($" --> {h.Key}: {string.Join(';', h.Value)}.");
    }

    //  Process the response body
    string responseBody = "NONE";

    try
    {
        //  Read the content as a string
        responseBody = await response.Content.ReadAsStringAsync();
    }
    catch
    {
        responseBody = "ERROR";
    }

    //  Return the api response
    return new ApiResponse
    {
        StatusCode = response.StatusCode,
        ResponseBody = responseBody,
        ValidResponse = !responseBody.Equals("NONE") && !responseBody.Equals("ERROR"),
        ResponseHeaders = response.Headers.ToDictionary(h => h.Key, h => string.Join(';', h.Value)),
    };
}

Output

 --> Authorization: Bearer e45jsh56.
 --> Test: test_value.
 --> User-Agent: VSpedSync/DevBuild.
Status Code: BadRequest.
Sign up to request clarification or add additional context in comments.

Comments

0

Maybe try to use the WebHeaderCollection.Add(HttpRequestHeader, String) overload method.

public static ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> headers,
    Dictionary<string, string> query, string method)
{
    //  Generate the query string
    string queryString = '?' +
        string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));

    //  Create request obejct
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(ApiServer + path + queryString));

    request.Timeout = 5000;
    request.UserAgent = "VSpedSync/DevBuild";
    request.Method = method;

    //  Set headers to the request
    foreach (KeyValuePair<string, string> h in headers)
    {
        if (h.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(HttpRequestHeader.Authorization, h.Value);
        }

        else if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(h.Key, h.Value);
        }
    }

    foreach (string requestHeader in request.Headers)
    {
        Debug.WriteLine(" --> " + requestHeader + ": " + request.Headers.Get(requestHeader));
    }

    // ...
    // .... Continue ....
    // ...
    return null;
}

1 Comment

Thanks for your code improvements! Unfortunately your suggestion produces the same results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.