本文介绍了调用 Web 服务时出现 HTTP 407 代理身份验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

代码如下:

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

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

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.

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

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

然后我注意到我们必须调用的所有 3rd 方网络服务都是 HTTPS.当我尝试将它们作为 HTTP 访问时,代理身份验证开始工作.为了让代理身份验证和 HTTPS 正常运行,我是否需要跳过一些额外的环节?

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?

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

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.

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

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.

推荐答案

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

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.

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

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

这篇关于调用 Web 服务时出现 HTTP 407 代理身份验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 07:51