C # How to pass cookie using shared HttpClient

I have the following setup:

JS client β†’ Web Api β†’ Web Api

I need to send an auth cookie all the way down. My problem is sending it from one web application to another. Due to integration with an older system using FormsAuthentication, I have to pass the auth cookie.

For performance reasons, I share the list of HttpClients (one for each web api) in the following dictionary:

private static ConcurrentDictionary<ApiIdentifier, HttpClient> _clients = new ConcurrentDictionary<ApiIdentifier, HttpClient>(); 

Therefore, given the identifier, I can grab the corresponding HttpClient.

The following works, but I'm sure this is bad code:

 HttpClient client = _clients[identifier]; var callerRequest = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage; string authCookieValue = GetAuthCookieValue(callerRequest); if (authCookieValue != null) { client.DefaultRequestHeaders.Remove("Cookie"); client.DefaultRequestHeaders.Add("Cookie", ".ASPXAUTH=" + authCookieValue); } HttpResponseMessage response = await client.PutAsJsonAsync(methodName, dataToSend); // Handle response... 

What is wrong is that 1) it seems wrong to manipulate DefaultRequestHeaders in the request and 2) potentially two simultaneous requests can ruin the cookies, because HttpClient is common.

I searched for a while without finding a solution, since most of which have the corresponding problem, creates an HttpClient instance for each request, therefore, it can set the required headers, which I try to avoid.

At some point, I received requests using HttpResponseMessage . Perhaps this may inspire a solution.

So my question is: is there a way to set cookies for one request using HttpClient, which will be safe for other clients using the same instance?

+5
source share
1 answer

Instead of calling PutAsJsonAsync (), you can use HttpRequestMessage and SendAsync ():

 Uri requestUri = ...; HttpMethod method = HttpMethod.Get /*Put, Post, Delete, etc.*/; var request = new HttpRequestMessage(method, requestUri); request.Headers.TryAddWithoutValidation("Cookie", ".ASPXAUTH=" + authCookieValue); request.Content = new StringContent(jsonDataToSend, Encoding.UTF8, "application/json"); var response = await client.SendAsync(request); 

UPDATE: So that your HTTP client does not store cookies from the response, you need to do this:

 var httpClient = new HttpClient(new HttpClientHandler() { UseCookies = false; }); 

Otherwise, you may get unexpected behavior with a single client and share other cookies.

+11
source

Source: https://habr.com/ru/post/1244135/


All Articles