C# 调用 Web 服务时出现 HTTP 407 代理身份验证错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2131933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:44:16  来源:igfitidea点击:

HTTP 407 proxy authentication error when calling a web service

c#.netauthenticationwindows-servicesproxy

提问by Christian Hayter

I'm working on a .NET app that calls 3rd party web services over the internet. The services do not use SOAP, so we manually construct an XML request document, send it to the service via HTTP, and retrieve an XML response.

我正在开发一个 .NET 应用程序,它通过 Internet 调用 3rd 方 Web 服务。服务不使用 SOAP,因此我们手动构建 XML 请求文档,通过 HTTP 将其发送到服务,并检索 XML 响应。

Our code is a Windows service that is run in the context of a normal Windows domain account, and sits behind a proxy server (Microsoft ISA Server) configured to require NTLM authentication. The account running our service has permission to access the internet through the proxy server.

我们的代码是在普通 Windows 域帐户上下文中运行的 Windows 服务,位于配置为需要 NTLM 身份验证的代理服务器(Microsoft ISA 服务器)之后。运行我们服务的帐户有权通过代理服务器访问互联网。

The code looks like this:

代码如下所示:

// Create the request object.
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";

// Configure for authenticating proxy server requiring Windows domain credentials.
request.Proxy = New WebProxy(proxyAddress) { UseDefaultCredentials = true };

// Set other required headers.
request.Accept = acceptableMimeType;
request.Headers.Add(HttpRequestHeader.AcceptCharset, acceptableCharset);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "none");
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-gb");
request.Headers.Add(HttpRequestHeader.CacheControl, "no-store");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "none");
request.Headers.Add(HttpRequestHeader.ContentLanguage, "en-gb");
request.ContentType = requestMimeType;
request.ContentLength = requestBytes.Length;

// Make the method call.
using(Stream stream = request.GetRequestStream()) {
    stream.Write(requestBytes, 0, requestBytes.Length);
}
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

// Extract the data from the response without relying on the HTTP Content-Length header
// (we cannot trust all providers to set it correctly).
const int bufferSize = 1024 * 64;
List<byte> responseBytes = new List<byte>();
using(Stream stream = new BufferedStream(response.GetResponseStream(), bufferSize)) {
    int value;
    while((value = stream.ReadByte()) != -1) {
        responseBytes.Add((byte) value);
    }
}

This works fine if the proxy server is turned off, or the URL has been whitelisted as not requiring authentication, but as soon as authentication is active, it always fails with an HTTP 407 error.

如果代理服务器关闭,或者 URL 已被列入白名单,因为不需要身份验证,这可以正常工作,但是一旦身份验证处于活动状态,它总是会失败并显示 HTTP 407 错误。

I put the above code in a test harness, and tried every method I could think of for configuring the request.Proxyproperty, without success.

我将上面的代码放在一个测试工具中,并尝试了我能想到的所有配置request.Proxy属性的方法,但没有成功。

I then noticed that all the 3rd party web services that we have to call are HTTPS. When I tried accessing them as HTTP instead, the proxy authentication started working. Is there some extra hoop I have to jump through to get proxy authentication and HTTPS to play nicely?

然后我注意到我们必须调用的所有 3rd 方 Web 服务都是 HTTPS。当我尝试将它们作为 HTTP 访问时,代理身份验证开始工作。是否有一些额外的障碍我必须跳过才能获得代理身份验证和 HTTPS 才能很好地发挥作用?

PS: The same problems occur with the open source SmoothWall proxy server, so I can't just write it off as a bug in ISA Server.

PS:开源的SmoothWall 代理服务器也会出现同样的问题,所以我不能把它当作ISA Server 中的一个bug 来写。

PPS: I'm aware that you can configure proxy settings in app.config, but (a) doing it in code shouldn't make any difference, and (b) the application design requires that we read the proxy settings from a database at runtime.

PPS:我知道您可以在 中配置代理设置app.config,但是 (a) 在代码中进行配置应该没有任何区别,并且 (b) 应用程序设计要求我们在运行时从数据库中读取代理设置。

采纳答案by Christian Hayter

I think I will have to write off this question. My original posted code does appear to work sometimes. Our proxy server is extremely unreliable; one minute it will block an internet connection from any software, and the next it will allow it. The IT guys seem powerless to do anything about it, and we (everyone outside the IT department) have no authority to make changes to the network infrastructure.

我想我将不得不注销这个问题。我的原始发布代码有时似乎确实有效。我们的代理服务器非常不可靠;一分钟它会阻止任何软件的互联网连接,下一分钟它会允许它。IT 人员似乎对此无能为力,我们(IT 部门以外的每个人)无权更改网络基础架构。

If anyone has any ideas on how to "harden" my code to compensate for an unreliable proxy server, then I'd be interested to hear them. :-)

如果有人对如何“强化”我的代码以补偿不可靠的代理服务器有任何想法,那么我很想听听他们的意见。:-)

回答by abhilash

Have you tried setting the proxy in the app.config ?

您是否尝试过在 app.config 中设置代理?

To disable the proxy, in the App.config file add the following configuration

要禁用代理,请在 App.config 文件中添加以下配置

<system.net>
  <defaultProxy enabled="false" useDefaultCredentials="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

To enable the proxy and to use the default proxy settings(specified in IE) add this configuration in your App.config

要启用代理并使用默认代理设置(在 IE 中指定),请在 App.config 中添加此配置

<system.net>
  <defaultProxy enabled="true" useDefaultCredentials="true">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

回答by AUSteve

Is there something wrong with your proxy server's certificate? If your service can't establish HTTPS then it will throw an error.

您的代理服务器的证书有问题吗?如果您的服务无法建立 HTTPS,则会引发错误。

回答by dbones

I did have a similar situation

我也有类似的情况

Did you noticed it worked when you accessed the internet before you ran the code? and if you had not accessed the internet for ages (20mins for me) you got the error.

在运行代码之前访问互联网时,您是否注意到它有效?如果您很久没有访问互联网(对我来说是 20 分钟),您就会收到错误消息。

have you tried to set the proxy credentials directly?

您是否尝试过直接设置代理凭据?

//setup the proxy
request.Proxy = new WebProxy("proxyIp", 8080);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;

I hope this fixes your issue too

我希望这也能解决您的问题