简体   繁体   中英

.NET Core Httpclient works but .Net Framework 4.7.2 httpclient doesn't

Sorry for the awful title, I'm not really sure how to phrase my issue in a short title format.

I'm trying to communicate with an external API. I make a basic authentication request to that API and get an x-csrf-token and a session token from the api.

I then make another request to that API, now using the x-csrf-token as a header and attach the session token to the header as "cookie".

The team that maintains the API sent me an example project that handles all of the above, and it looks like this:

public static async Task<string> Send(string apiname, string value)
{
    // Fetch the authorization tokens from SAP
    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri(basePath);
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(user + ":" + password)));
    client.DefaultRequestHeaders.Add("x-csrf-token", "Fetch");
    string csrfToken = "";
    string sessionCookie = "";
    HttpResponseMessage response = await client.GetAsync(string.Empty);
    IEnumerable<string> values;
    if (response.Headers.TryGetValues("x-csrf-token", out values))
    {
        csrfToken = values.FirstOrDefault();
    }
    if (response.Headers.TryGetValues("set-cookie", out values))
    {
        sessionCookie = values.Where(s => s.StartsWith("SAP_SESSION")).FirstOrDefault();
    }

    // Reinstantiate the HttpClient, adding the tokens we just got from SAP
    client = new HttpClient();
    client.DefaultRequestHeaders.Add("x-csrf-token", csrfToken);
    client.DefaultRequestHeaders.Add("cookie", sessionCookie);
    client.BaseAddress = new Uri(basePath);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    // Have to parse the string this way otherwise it'll break the dates
    JToken token;
    using (var sr = new StringReader(value))
    using (var jr = new JsonTextReader(sr) { DateParseHandling = DateParseHandling.None })
    {
        token = JToken.ReadFrom(jr);
    }
    HttpResponseMessage response2 = await client.PostAsJsonAsync(apiname, token);
    string responseBody = await response2.Content.ReadAsStringAsync();
    return responseBody;
}

This all works great as a .NET Core webAPI (and also as a .netcore console app).

Interestingly enough (in my opinion anyway), when I use the exact same code in a .net 4.7.2 project, it doesn't append the "cookie" header properly, and so I'm getting an unauthorized redirect back from the API.

To be absolutely sure that I didn't change any code, I started from scratch with a brand new .netcore 2.0 console app and a brand new .net 4.7.2 console app and copy-pasted the exact same code and installed the same nuget packages (Newtonsoft.JSON and Microsoft.WebApi.Client). I inspected my web traffic with fiddler (seen below) and you can see that in .netcore, the cookie appends properly and everything works, but in .net 4.7.2, the API returns a redirect to authenticate.

在此输入图像描述

.Net Framework uses Cookie Container.

Also core, perhaps its a better implementation then what you are doing now and more supported.

Please see cookie container docs

Small example:

  var cookieContainer = new CookieContainer();
            this.handler = new HttpClientHandler
            {
                CookieContainer = cookieContainer,
                UseCookies = true
            };
            client = new HttpClient(handler);

HttpClient will eat the custom cookie if you do not set UseCookies to false ,

using (var handler = new HttpClientHandler { UseCookies = false })
using (client = new HttpClient(handler) { BaseAddress = new Uri(Path) }){
      client.DefaultRequestHeaders.Add("cookie", cookieValue);
}

It will try to use the cookie container and at the same time ignore any custom cookie headers, very frustrating behavior if you ask me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM