gpt4 book ai didi

c# - 如何使用 Windows 身份验证防止重复的 HTTP 请求

转载 作者:可可西里 更新时间:2023-11-01 08:48:40 35 4
gpt4 key购买 nike

我正在开发基于 WCF 的客户端/服务器应用程序(WCF 是自托管的,不在 IIS 中)。

WCF 服务有一个操作可以将一大块数据上传到服务器。契约(Contract)大致如下所示:

void UploadChunk(int clientId, byte[] chunk);

我们正在使用 Windows 身份验证 (Kerberos/NTLM),因此我们无法在此处使用流式传输。

绑定(bind)看起来像这样(客户端和服务器端):

new BasicHttpBinding
{
Security = new BasicHttpSecurity
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Transport = { ClientCredentialType = HttpClientCredentialType.Windows },
},
MaxReceivedMessageSize = 0x7fffffff,
ReaderQuotas = { MaxArrayLength = 0x800000 },
};

客户端通过派生自 System.ServiceModel.ClientBase<TChannel> 的代理对象与服务对话.

所有这些都工作得很好,但我们观察到 WCF 客户端将每个 HTTP 请求发送两次,一次没有 auth header ,另一次带有正确的 auth header 。这是有问题的,因为请求将非常大,并且此行为导致请求大小是实际 block 大小的两倍。

我已经发现 ( https://weblog.west-wind.com/posts/2010/Feb/18/NET-WebRequestPreAuthenticate-not-quite-what-it-sounds-like ) 设置 WebRequest.PreAuthenticatetrue记住身份验证 header 并将其重新用于后续请求。

然而,据我所知,到目前为止,WCF 并未公开修改 WebRequest 实例的机制。

这个问题有解决办法吗?

最佳答案

对于 Windows 身份验证,您的第一个请求总是会收到质询响应 (401)。

如果您控制所有客户端,我认为最实用的解决方案是使用最小负载实现操作。

操作 void IsAuthenticated() 应该做。对于每个客户端代理实例,您将在 UploadChunk 之前调用 IsAuthenticated

IsAuthenticated 请求将使您通过 401 质询响应而无需发送大量负载,但会验证连接。对该连接的后续请求将不会受到挑战。

编辑:

我描述的行为似乎只适用于 IIS 8。所以我仔细查看了两个 http.sys 跟踪,一个用于 IIS 托管服务,一个用于自托管服务。

IIS 托管服务似乎在身份验证方面使用了某种优化。使用 Authenticator Sspi Authenticator 对连接的第一个请求进行身份验证。后续请求使用 Fast Authenticator 进行身份验证。

这些事件都没有出现在自托管跟踪中,这使我得出结论,即自托管未针对 Windows 身份验证进行优化。

http.sys - trace IIS

http.sys - trace self host

然后我找到this blog entry提出了一个使用 NTLM 的解决方案,一个自定义绑定(bind)和 HTTP 传输的 unsafeConnectionNtlmAuthentication 设置。如果您愿意只使用 NTLM 并且 documentation 中强调的安全问题根据 http.sys 跟踪,这不是问题这似乎提供了您正在寻找的行为

http.sys trace - self host with custom binding

对于服务器使用绑定(bind)

<customBinding>
<binding name="myBinding">
<textMessageEncoding messageVersion="Soap11" />
<httpTransport authenticationScheme="Ntlm" unsafeConnectionNtlmAuthentication="true"/>
</binding>
</customBinding>

对于您的客户端,您可以使用具有 Ntlm 安全性的常规 basicHttpBinding:

<basicHttpBinding>
<binding name="BasicHttpBinding_ITest">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
</binding>
</basicHttpBinding>

关于c# - 如何使用 Windows 身份验证防止重复的 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36185363/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com