【发布时间】:2011-01-09 01:41:06
【问题描述】:
我正在开发一个通过 Internet 调用第 3 方 Web 服务的 .NET 应用程序。服务不使用 SOAP,因此我们手动构建 XML 请求文档,通过 HTTP 将其发送到服务,并检索 XML 响应。
我们的代码是在普通 Windows 域帐户的上下文中运行的 Windows 服务,位于配置为需要 NTLM 身份验证的代理服务器(Microsoft ISA 服务器)后面。运行我们服务的帐户有权通过代理服务器访问互联网。
代码如下:
// 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 错误。
我将上面的代码放在一个测试工具中,并尝试了我能想到的所有方法来配置request.Proxy 属性,但没有成功。
然后我注意到我们必须调用的所有第 3 方 Web 服务都是 HTTPS。当我尝试以 HTTP 方式访问它们时,代理身份验证开始工作。是否有一些额外的障碍我必须跳过才能获得代理身份验证和 HTTPS 才能很好地发挥作用?
PS:开源的 SmoothWall 代理服务器也会出现同样的问题,所以我不能把它当作 ISA Server 中的一个 bug 写下来。
PPS:我知道您可以在 app.config 中配置代理设置,但是 (a) 在代码中执行此操作应该没有任何区别,并且 (b) 应用程序设计要求我们从运行时的数据库。
【问题讨论】:
标签: c# .net authentication windows-services proxy