【发布时间】:2026-01-11 07:45:02
【问题描述】:
我正在开发基于 WCF 的客户端/服务器应用程序(WCF 是自托管的,而不是在 IIS 中)。
WCF 服务有一个将数据块上传到服务器的操作。合约大致是这样的:
void UploadChunk(int clientId, byte[] chunk);
我们正在使用 Windows 身份验证 (Kerberos/NTLM),因此我们无法在此处使用流式传输。
绑定看起来像这样(客户端和服务器端):
new BasicHttpBinding
{
Security = new BasicHttpSecurity
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Transport = { ClientCredentialType = HttpClientCredentialType.Windows },
},
MaxReceivedMessageSize = 0x7fffffff,
ReaderQuotas = { MaxArrayLength = 0x800000 },
};
客户端通过派生自System.ServiceModel.ClientBase<TChannel> 的代理对象与服务对话。
所有这些都可以正常工作,但我们观察到 WCF 客户端发送每个 HTTP 请求两次,一次没有 auth 标头,另一次使用正确的 auth 标头。这是有问题的,因为请求会非常大,而且这种行为会导致请求大小是实际块大小的两倍。
我已经发现 (https://weblog.west-wind.com/posts/2010/Feb/18/NET-WebRequestPreAuthenticate-not-quite-what-it-sounds-like) 将 WebRequest.PreAuthenticate 设置为 true 会记住 auth 标头并将其重用于后续请求。
但是,到目前为止,WCF 并未公开修改 WebRequest 实例的机制。
这个问题有什么解决办法吗?
【问题讨论】:
-
"WCF 将每个 HTTP 请求发送两次" - 这是不正确的。 WCF 是一个服务器 端平台——它自己不发出任何请求。你用的是什么客户端?如果您使用的是 SOAP,您是使用服务参考(也称为服务代理)还是编写自己的客户端?
-
我们从 ClientBase
派生。 TChannel 是我们在客户端和服务器程序集之间共享的合约接口(我编辑了问题以反映这一点) -
既然已经是 Kerberos,那就收集痕迹看看到底发生了什么。来自服务器的响应消息应该会告诉您原因。
-
WCF 跟踪没有显示重复的请求,可能是因为 Kerberos 握手是由 Windows (HTTP.sys) 完成的
-
在旁注中,您为什么声明您没有使用流,因为您使用的是 Windows 身份验证? Windows 身份验证是一种传输级别的安全选项,因此它不应禁止使用流。
标签: c# wcf windows-authentication