HTTP 客户端未向代理服务器 C# 进行身份验证

Posted

技术标签:

【中文标题】HTTP 客户端未向代理服务器 C# 进行身份验证【英文标题】:HTTP Client is not authenticating to proxy server C# 【发布时间】:2018-05-29 01:38:10 【问题描述】:

我正在尝试使用凭据从客户端站点的 Windows 服务向代理服务器进行身份验证,但不断收到以下响应:

StatusCode:407,ReasonPhrase:“需要代理身份验证”,版本:1.1,内容:System.Net.Http.StreamContent,标头: 编译指示:无缓存 代理连接:关闭 连接:关闭 缓存控制:无缓存 代理验证:NTLM 设置 Cookie:BCSI-CS-2737f33ff5b5f739=2;路径=/ 内容长度:1351 内容类型:文本/html;字符集=utf-8

我的本​​地代理配置完全不同,我无法重新创建问题。这是我用来向服务器进行身份验证的代码。 (如代码中所述,它基于:HttpClient and using proxy - constantly getting 407

 private HttpClient GenerateHttpClientWithProxySettings()

    //Code based on https://***.com/questions/29856543/httpclient-and-using-proxy-constantly-getting-407

    // First create a proxy object
    var proxy = new WebProxy()
    
        Address = new Uri($"Settings.ProxyAddress:Settings.PortNumber"),
        BypassProxyOnLocal = false,
        UseDefaultCredentials = false,
        // *** These creds are given to the proxy server, not the web server ***
        Credentials = new NetworkCredential(
            userName: Settings.ProxyUserName,
            password: Settings.ProxyPassword)
    ;

    //Debug:
    Settings.log.Debug($"Settings.ProxyAddress:Settings.PortNumber");
    Settings.log.Debug(Settings.ProxyUserName);
    Settings.log.Debug(Settings.ProxyPassword);

    // Now create a client handler which uses that proxy
    var httpClientHandler = new HttpClientHandler()
    
        Proxy = proxy,
        UseProxy = true,
        AllowAutoRedirect = true,
    ;

    //// Omit this part if you don't need to authenticate with the web server:
    //if (needServerAuthentication)
    //
    //    httpClientHandler.PreAuthenticate = true;
    //    httpClientHandler.UseDefaultCredentials = false;

    //    // *** These creds are given to the web server, not the proxy server ***
    //    httpClientHandler.Credentials = new NetworkCredential(
    //        userName: serverUserName,
    //        password: serverPassword);
    //

    // Finally, create the HTTP client object
    HttpClient client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
    return client;



//Get
private async Task<ReturnedData> GetRequestWithProxy(string url)

    ReturnedData result = new ReturnedData();
    using (HttpClient client = GenerateHttpClientWithProxySettings())
    
        using (HttpResponseMessage message = await client.GetAsync(url))
        
            Settings.log.Debug("[[message:]]");
            Settings.log.Debug(message.ToString());
            result.StatusCode = message.StatusCode.ToString();
            result.Succceded = message.IsSuccessStatusCode;
            using (HttpContent content = message.Content)
            
                Settings.log.Debug("[[content:]]");
                Settings.log.Debug(content.ToString());
                result.Content = await message.Content.ReadAsStringAsync();
                return result;
            
        
    



// Post 
private async Task<ReturnedData> PostRequestWithProxy(string url, dynamic payload)

    ReturnedData result = new ReturnedData();
    string stringPayload = await Task.Run(() => JsonConvert.SerializeObject(payload));
    // Wrap our JSON inside a StringContent which then can be used by the HttpClient class
    using (var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json"))
    
        using (HttpClient client = GenerateHttpClientWithProxySettings())
        
            using (HttpResponseMessage message = await client.PostAsync(url, httpContent))
            
                Settings.log.Debug(message.ToString());
                result.StatusCode = message.StatusCode.ToString();
                result.Succceded = message.IsSuccessStatusCode;
                using (HttpContent content = message.Content)
                
                    Settings.log.Debug(content.ToString());
                    result.Content = await message.Content.ReadAsStringAsync();
                    return result;
                
            
        
    

对于我在这里做错的任何帮助将不胜感激。

谢谢!

【问题讨论】:

Windows 服务在哪个账户下运行? SYSTEM 还是登录用户? 【参考方案1】:

从响应头

Proxy-Authenticate: NTLM

代理接受 Windows 凭据而不是用户名/密码。

试试这个

var proxy = new WebProxy()

    ...
    UseDefaultCredentials = true
    /*Credentials = new NetworkCredential(
        userName: Settings.ProxyUserName,
        password: Settings.ProxyPassword)*/
;

【讨论】:

以上是关于HTTP 客户端未向代理服务器 C# 进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

C# 407 需要代理身份验证

Http客户端。在自动发现的代理上进行身份验证的默认凭据

无法创建 SSL/TLS 安全通道 - 问题可能出在代理服务器上吗?

无法通过代理进行隧道传输。代理通过 https 返回“HTTP/1.1 407”

将哪些 Java 属性传递给 Java 应用程序以使用 http 代理进行身份验证

通过 PHP 会话进行服务器身份验证