WCF客户端端点:不带< dns>的SecurityNegotiationException; [英] WCF client endpoint: SecurityNegotiationException without <dns>

查看:96
本文介绍了WCF客户端端点:不带< dns>的SecurityNegotiationException;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里遇到一个奇怪的情况。我知道了,但是我不明白为什么。
情况如下:



我的应用程序(网站)必须调用WCF服务。 WCF服务公开netTcpBinding,并且需要传输安全性(Windows)。
客户端和服务器位于同一域中,但位于不同的服务器上。

因此,生成客户端会导致以下配置(大多数是默认设置)

 < system.serviceModel> 
< bindings>
< netTcpBinding>
< binding name = MyTcpEndpoint ...>
< reliableSessionordered = true inactivityTimeout = 00:10:00
enabled = false />
< security mode = Transport>
< transport clientCredentialType = Windows protectionLevel = EncryptAndSign />
< message clientCredentialType = Windows />
< / security>
< / binding>
< / netTcpBinding>
< / bindings>
< client>
<端点地址= net.tcp:// localhost:xxxxx / xxxx / xxx / 1.0
binding = netTcpBinding bindingConfiguration = MyTcpEndpoint
contract = Service.IMyService name = TcpEndpoint />
< / client>
< /system.serviceModel>

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

  System.ServiceModel.Security.SecurityNegotiationException:目标名称不正确或服务器已拒绝客户端凭据。 ---> System.Security.Authentication.InvalidCredentialException:目标名称不正确或服务器已拒绝客户端凭据。 ---> System.ComponentModel.Win32Exception:登录尝试失败
-内部异常堆栈跟踪结束--- System.Net.Security.NegoState.EndProcessAuthentication(IAsyncResult result)处
.Net.Security.NegotiateStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.InitiateUpgradeAsyncResult.OnCompleteAuthenticateAsClient(IAsyncResult result)
at System.ServiceModel.Channels。结果)
---内部异常堆栈跟踪的末尾---

服务器堆栈跟踪:System.ServiceModel.AsyncResult.End [TAsyncResult](IAsyncResult result)$
System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult结果)处的b $ b System.ServiceModel.Channels.ServiceChannel.EndCall(字符串操作,Object []输出,IAsyncResu)处的
lt result)
....

现在,如果我只是更改这样的客户端:

 <端点地址= net.tcp:// localhost:xxxxx / xxxx / xxx / 1.0 
binding = netTcpBinding bindingConfiguration = MyTcpEndpoint
contract = Service.IMyService name = TcpEndpoint>
< identity>
< dns />
< / identity>
< / endpoint>

一切正常,我的服务器高兴地报告它是由托管AppPool的服务帐户调用的网站。一切都很好。



我现在的问题是:为什么这样做有效?这是做什么的?我只是通过反复试验就获得了这种解决方案。在我看来,所有< dns /> 标记所做的只是告诉客户端使用默认DNS进行身份验证,但是它不是这样做吗? / p>

更新

因此,经过更多研究和反复试验后,我仍然没有找到答案这个问题。
在某些情况下,如果我不提供< dns /> ,我会拒绝凭据错误,但是如果我提供< dns value = whatever /> config,则可以。为什么?

解决方案

< dns /> 标签允许客户端验证服务器身份。例如,如果您说< dns value = google.com /> ,它将验证WCF服务器是否提供google.com身份。由于您说< dns /> ,它可能只允许所有人为您服务。



更多信息,请参见< a href = http://msdn.microsoft.com/en-us/library/ms733130.aspx rel = noreferrer>服务身份和身份验证


I'm having a strange situation here. I got it working, but I don't understand why. Situation is as follows:

There is a WCF service which my application (a website) has to call. The WCF service exposes a netTcpBinding and requires Transport Security (Windows). Client and server are in the same domain, but on different servers.
So generating a client results in the following config (mostly defaults)

<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>

When I run the website and make the call to the service, I get the following error:

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)
....

Now, if I just alter the configuration of the client like so:

    <endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" 
               binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" 
               contract="Service.IMyService" name="TcpEndpoint">
        <identity>
            <dns />
        </identity> 
  </endpoint>

everything works and my server happily reports that it got called by the service account which hosts the AppPool for my website. All good.

My question now is: why does this work? What does this do? I got to this solution by mere trial-and-error. To me it seems that all the <dns /> tag does is tell the client to use the default DNS for authentication, but doesn't it do that anyway?

UPDATE
So after some more research and trial-and-error, I still haven't found an answer to this problem. In some cases, if I don't provide the <dns />, I get the Credentials rejected error, but if I provide the <dns value="whatever"/>config, it works. Why?

解决方案

<dns/> tag allows the client to verify the server identity. For example if you said <dns value="google.com"/> it would verify that the WCF server provides google.com identity. Since you say <dns/> it probably just allows everybody to serve you.

More info at Service Identity and Authentication

这篇关于WCF客户端端点:不带&lt; dns&gt;的SecurityNegotiationException;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆