WCF客户端端点:没有<dns>的SecurityNegotiationException

Roe*_*elF 21 dns configuration wcf wcf-client wcf-security

我在这里遇到一种奇怪的情况.我搞定了,但我不明白为什么.情况如下:

我的应用程序(网站)必须调用WCF服务.WCF服务公开netTcpBinding并需要传输安全性(Windows).客户端和服务器位于同一个域中,但位于不同的服务器上.
因此生成客户端会导致以下配置(主要是默认值)

<system.serviceModel>
    <bindings>
      <netTcpBinding>
         <binding name="MyTcpEndpoint" ...>          
              <reliableSession ordered="true" inactivityTimeout="00:10:00"
                              enabled="false" />
             <security mode="Transport">
                <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
                <message clientCredentialType="Windows" />
            </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client> 
        <endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" 
                   binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" 
                   contract="Service.IMyService" name="TcpEndpoint"/>
    </client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

当我运行网站并调用该服务时,我收到以下错误:

System.ServiceModel.Security.SecurityNegotiationException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.Security.Authentication.InvalidCredentialException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.ComponentModel.Win32Exception: The logon attempt failed
    --- End of inner exception stack trace ---
    at System.Net.Security.NegoState.EndProcessAuthentication(IAsyncResult result)
    at System.Net.Security.NegotiateStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
    at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.InitiateUpgradeAsyncResult.OnCompleteAuthenticateAsClient(IAsyncResult result)
    at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorAsyncResult.CompleteAuthenticateAsClient(IAsyncResult result)
    --- End of inner exception stack trace ---

Server stack trace: 
    at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
    at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
    at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
....
Run Code Online (Sandbox Code Playgroud)

现在,如果我只是改变客户端的配置:

    <endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" 
               binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" 
               contract="Service.IMyService" name="TcpEndpoint">
        <identity>
            <dns />
        </identity> 
  </endpoint>
Run Code Online (Sandbox Code Playgroud)

一切正常,我的服务器愉快地报告它是由我的网站托管AppPool的服务帐户调用的.都好.

我现在的问题是:为什么这有效?这是做什么的?仅通过反复试验就得出了这个解决方案.对我来说,似乎所有<dns />标签都告诉客户端使用默认的DNS进行身份验证,但是不管怎么说它不会这样做吗?

更新
因此,经过一些更多的研究和反复试验,我仍然没有找到这个问题的答案.在某些情况下,如果我不提供<dns />,我得到Credentials rejected错误,但如果我提供<dns value="whatever"/>配置,它的工作原理.为什么?

Vit*_*lik 17

<dns/>tag允许客户端验证服务器身份.例如,如果您说<dns value="google.com"/>它将验证WCF服务器是否提供google.com身份.既然你说它<dns/>可能只是让每个人都能为你服务.

有关服务标识和身份验证的详细信息


Ran*_*Ian 7

MSDN的"服务身份和身份验证"解释了端点身份部分可以实现针对网络钓鱼方案的客户端安全预防措施.

来自MSDN:

在客户端启动与端点的通信并且服务向客户端验证自身之后,客户端将端点身份值与端点身份验证过程返回的实际值进行比较.如果它们匹配,则确保客户端已联系预期的服务端点.这可以防止客户端被重定向到恶意服务托管的端点,从而起到防止网络钓鱼的作用.

另请参阅MSDN的"服务标识示例".