防止后续服务调用上的协商握手

Cor*_*son 5 .net c# wcf soap windows-authentication

我正在呼唤使用Windows身份验证的SOAP服务.这是我的配置:

new BasicHttpBinding
{
    Security = new BasicHttpSecurity
    {
        Mode = BasicHttpSecurityMode.TransportCredentialOnly,
        Transport = new HttpTransportSecurity
        {
            ClientCredentialType = HttpClientCredentialType.Windows
        }
    },
};
Run Code Online (Sandbox Code Playgroud)

我在这里手动设置凭据,因为用户位于不同的域中:

client.ClientCredentials.Windows.ClientCredential.Domain = "...";
client.ClientCredentials.Windows.ClientCredential.UserName = "...";
client.ClientCredentials.Windows.ClientCredential.Password = "...";
Run Code Online (Sandbox Code Playgroud)

我注意到我通过客户端代理进行的每次通话都会导致三次访问:

Request: POST /EndPoint (no auth)
Response: 401 Unauthorized, WWW-Authenticate: Negotiate

Request: POST /EndPoint, Authorization: Negotiate
Response: 401 Unauthorized, WWW-Authenticate: Negotiate <gunk>

Request: Post /EndPoint, Authorization: Negotiate <gunk>
Response: 200 OK
Run Code Online (Sandbox Code Playgroud)

如果这只发生在第一次调用时它不会那么可怕,但它会发生在对同一客户端代理实例的所有后续调用中.

我呼叫的服务器不在我的控制之下,并且具有不可忽视的延迟,所以我很想找到一种方法来消除这些冗余的旅行.可能吗?

mil*_*nio 2

我刚刚使用您的绑定设置和手动 un+pwd 身份验证使用 WCF 服务创建了虚拟客户端。WCF 服务设置为接受 Windows 身份验证。

但是,就我而言,所有后续调用都会自动进行身份验证。

Request: Post /Service1.svc
Run Code Online (Sandbox Code Playgroud)

回应1:

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Run Code Online (Sandbox Code Playgroud)

回应2:

HTTP/1.1 401 Unauthorized
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
WWW-Authenticate: Negotiate xxxxxxxxxxxxxxxxxxxxxxxxxx.....
Run Code Online (Sandbox Code Playgroud)

回应3:

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 202
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
WWW-Authenticate: Negotiate xxxxxxx....
Run Code Online (Sandbox Code Playgroud)

在响应标头中,我有Persistent-Auth: true. 这对你来说也是一样吗?如果不是 - IIS 中的设置可以强制客户端在每次请求后进行身份验证 - 请参阅此MSDN 帖子

基本上,我想你必须在服务器上:

authPersistSingleRequest =  False
authPersistNonNTLM = True
Run Code Online (Sandbox Code Playgroud)

然后就可以了。