4
votes

I am trying to use credentials to authenticate to a proxy server from a windows service at a client site but keep getting the following response:

StatusCode: 407, ReasonPhrase: 'Proxy Authentication Required', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: {
Pragma: no-cache
Proxy-Connection: close
Connection: close
Cache-Control: no-cache
Proxy-Authenticate: NTLM
Set-Cookie: BCSI-CS-2737f33ff5b5f739=2; Path=/
Content-Length: 1351
Content-Type: text/html; charset=utf-8
}

My local proxy is configured quite differently, and i cannot recreate the issue. Here is the code that i am using to authenticate with the server. (As mentioned in the code it is based on: HttpClient and using proxy - constantly getting 407

 private HttpClient GenerateHttpClientWithProxySettings()
{
    //Code based on https://stackguides.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;
                }
            }
        }
    }
}

Any help on what i am doing wrong here would be greatly appreciated.

Thanks!

1
Which account is the Windows service running under? SYSTEM or a the logon user?kennyzx

1 Answers

1
votes

From the response header

Proxy-Authenticate: NTLM

The proxy accepts Windows credential instead of username/password.

Try this instead

var proxy = new WebProxy()
{
    ...
    UseDefaultCredentials = true
    /*Credentials = new NetworkCredential(
        userName: Settings.ProxyUserName,
        password: Settings.ProxyPassword)*/
};