C#WebRequest删除GET请求上的Authorization标头

时间:2020-01-10 21:21:07

标签: c# authorization webrequest

我正在尝试与某些服务器通信,但是当我使用GET请求时,Authorization标头被删除了。

我的代码(请原谅):

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

这就是我所说的方法:

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

使用GET方法时发送的标头:

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

使用POST方法时发送的标头:

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

我做错什么了吗?

编辑:似乎有待解决。我现在使用的是RestSharp,而不是普通的WebRequest。

2 个答案:

答案 0 :(得分:0)

也许尝试使用WebHeaderCollection.Add(HttpRequestHeader, String)重载方法。

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 :(得分:0)

您可以尝试使用HttpClient代替WebRequest。我尝试了以下操作,授权标头在发送后保留在请求中。

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

输出

 --> Authorization: Bearer e45jsh56.
 --> Test: test_value.
 --> User-Agent: VSpedSync/DevBuild.
Status Code: BadRequest.