C# 设置';根据请求';带有.Net HttpClient的cookie

C# 设置';根据请求';带有.Net HttpClient的cookie,c#,cookies,owin,dotnet-httpclient,C#,Cookies,Owin,Dotnet Httpclient,嗨,我正在尝试使用Owin基础设施实现简单的http代理服务。此代理必须使用windows身份验证对用户进行身份验证,从企业广告中提取用户的属性,将此信息作为cookie值添加到原始请求中,然后将请求重定向到Internet上的应用程序(我们称之为外部应用程序) 我正在使用HttpClient向外部应用程序发送请求 然而,HttpClient并不适合这种情况。似乎唯一允许使用它发送cookie的方法是将它们放入CookieContainer并将此CookieContainer设置为HttpCli

嗨,我正在尝试使用Owin基础设施实现简单的http代理服务。此代理必须使用windows身份验证对用户进行身份验证,从企业广告中提取用户的属性,将此信息作为cookie值添加到原始请求中,然后将请求重定向到Internet上的应用程序(我们称之为外部应用程序)

我正在使用HttpClient向外部应用程序发送请求

然而,HttpClient并不适合这种情况。似乎唯一允许使用它发送cookie的方法是将它们放入CookieContainer并将此CookieContainer设置为HttpClientHandler的属性。当您只有一个用户时,这是可以的,但在代理服务的情况下,来自不同用户的cookie值将相互混合并覆盖

有没有办法为每个请求设置cookie或CookieContainer?或者有更好的方法重定向请求

请注意,以下是一些代码:

http处理程序的初始化:

    private void RegisterRoutes(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "Proxy",
            routeTemplate: "{*path}",
            handler: HttpClientFactory.CreatePipeline
                (
                    innerHandler: new HttpClientHandler(),
                    handlers: new DelegatingHandler[]
                    {
                        new ProxyHandler()
                    }
                ),
            defaults: new { path = RouteParameter.Optional },
            constraints: null);
    }
ProxyHandler 内部类ProxyHandler:DelegatingHandler { 私有只读HttpClient\u客户端

    public ProxyHandler()
    {
        var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic};

        _client = new HttpClient(handler);
    }

    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var forwardUri = new UriBuilder(request.RequestUri);
        forwardUri.Host = "localhost";
        forwardUri.Port = 23016;
        forwardUri.Scheme = Uri.UriSchemeHttp;

        request.RequestUri = forwardUri.Uri;
        request.Headers.Host = forwardUri.Host;

        //Explicitly null it to avoid protocol violation
        if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Trace)
            request.Content = null;

        try
        {
            var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);

            //Explicitly null it to avoid protocol violation
            if (request.Method == HttpMethod.Head)
                response.Content = null;
            return response;
        }
        catch (Exception ex)
        {
            var response = request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            string message = ex.Message;
            if (ex.InnerException != null)
                message += ':' + ex.InnerException.Message;
            response.Content = new StringContent(message);
            Trace.TraceError("Error:{0}", message);
            return response;
        }
    }

    private void SetCookies(HttpRequestMessage request)
    {
        var container = new CookieContainer();

        var authCookieValue = "2EF91D8FD9EDC594F2DB82";
        var authCookie = new Cookie("cookieByProxy", authCookieValue);

        var targetUri = new Uri("http://localhost:23016/");
        container.Add(targetUri, authCookie);

        var cookieHeader = container.GetCookieHeader(targetUri);

        if (!string.IsNullOrEmpty(cookieHeader))
            request.Headers.TryAddWithoutValidation("Cookie", cookieHeader);//Overwriting cookie header with custom values. However cookie values are ignored by HttpClient (both old and new)
    }
}
publicproxyhandler()
{
var handler=newhttpclienthandler{ClientCertificateOptions=ClientCertificateOptions.Automatic};
_客户机=新的HttpClient(处理程序);
}
受保护的异步覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
var forwardUri=新的UriBuilder(request.RequestUri);
forwardUri.Host=“localhost”;
forwardUri.Port=23016;
forwardUri.Scheme=Uri.UriSchemeHttp;
request.RequestUri=forwardUri.Uri;
request.Headers.Host=forwardUri.Host;
//显式为空以避免协议冲突
if(request.Method==HttpMethod.Get | | request.Method==HttpMethod.Trace)
request.Content=null;
尝试
{
var response=wait_client.sendaync(请求,HttpCompletionOption.ResponseHeadersRead,cancellationToken);
//显式为空以避免协议冲突
if(request.Method==HttpMethod.Head)
response.Content=null;
返回响应;
}
捕获(例外情况除外)
{
var response=request.CreateErrorResponse(HttpStatusCode.InternalServerError,ex);
字符串消息=例如消息;
if(例如InnerException!=null)
message+=':'+ex.InnerException.message;
response.Content=新的StringContent(消息);
Trace.TraceError(“错误:{0}”,消息);
返回响应;
}
}
私有void SetCookies(HttpRequestMessage请求)
{
var container=新的CookieContainer();
var authCookieValue=“2EF91D8FD9EDC594F2DB82”;
var authCookie=新Cookie(“cookieByProxy”,authCookieValue);
var targetUri=新Uri(“http://localhost:23016/");
container.Add(targetUri、authCookie);
var cookieHeader=container.GetCookieHeader(targetUri);
如果(!string.IsNullOrEmpty(cookieHeader))
request.Headers.TryAddWithoutValidation(“Cookie”,cookieHeader);//使用自定义值覆盖Cookie头。但是,HttpClient会忽略Cookie值(新旧)
}
}
在这里找到了解决方案: 诀窍在于显式地将HttpClientHandler的UseCookie标志设置为false

var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic, UseCookie = false };

谢谢你的建议,但我真的期待高流量。