C#如何使用共享的HttpClient传递cookie

我有以下设置:

JS客户端 – > Web Api – > Web Api

我需要一直向下发送auth cookie。 我的问题是从一个web api发送到另一个。 由于与使用FormsAuthentication的旧系统集成,我必须传递auth cookie。

出于性能原因,我在以下字典中共享一个HttpClients列表(每个web api一个):

private static ConcurrentDictionary _clients = new ConcurrentDictionary(); 

所以给定一个标识符,我可以获取相应的HttpClient。

以下工作,但我很确定这是错误的代码:

 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... 

关于这一点的错误是1)在请求中操作DefaultRequestHeaders似乎是错误的; 2)可能两个同时发生的请求可能会破坏cookie,因为HttpClient是共享的。

我一直在寻找一段时间而没有找到解决方案,因为大多数具有匹配问题的实例化每个请求的HttpClient,因此能够设置所需的标头,我正在努力避免。

有一次,我得到了使用HttpResponseMessage请求。 也许这可以成为解决方案的灵感来源。

所以我的问题是:有没有办法使用HttpClient为单个请求设置cookie,这对于使用相同实例的其他客户端是否安全?

您可以使用HttpRequestMessage和SendAsync()代替调用PutAsJsonAsync():

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

更新:要确保您的HTTP客户端不存储响应中的任何cookie,您需要执行此操作:

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

否则,您可能会通过使用一个客户端并共享其他cookie来获得意外行为。