WCF:为什么传递远程终结点失败?

16

WCF:为什么直接传递远程终结点失败,而通过配置文件传递相同的终结点却可以成功?

以下代码可以正常工作:

    Using con As New OfferingTap.OfferingTapClient(New ServiceModel.InstanceContext(callback), "NetTcpBinding_IOfferingTap"

这样不行:

    Using con As New OfferingTap.OfferingTapClient(New ServiceModel.InstanceContext(callback), "NetTcpBinding_IOfferingTap", "net.tcp://qa1offerings:8190/")
Configuration File Excerpt:
        <endpoint address="net.tcp://qa1offerings:8190/" binding="netTcpBinding"
            bindingConfiguration="NetTcpBinding_IOfferingTap" contract="OfferingTap.IOfferingTap"
            name="NetTcpBinding_IOfferingTap">

异常:

System.ServiceModel.Security.SecurityNegotiationException was unhandled
  Message="A call to SSPI failed, see inner exception."
  Source="mscorlib"
  StackTrace:
    Server stack trace: 
       at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
       at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUpgrade(Stream stream)
       at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
       at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
       at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
       at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
       at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
       at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]: 
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at Offering_Server_Recorder.OfferingTap.IOfferingTap.RequestFeed(Int32 dataSourceKey)
       at Offering_Server_Recorder.OfferingTap.OfferingTapClient.RequestFeed(Int32 dataSourceKey) in C:\Documents and Settings\jallen\Local Settings\Application Data\Temporary Projects\Offering Server Recorder\Service References\OfferingTap\Reference.vb:line 471
       at Offering_Server_Recorder.Module1.Main() in C:\Documents and Settings\jallen\Local Settings\Application Data\Temporary Projects\Offering Server Recorder\Module1.vb:line 9
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Security.Authentication.AuthenticationException
       Message="A call to SSPI failed, see inner exception."
       Source="System"
       StackTrace:
            at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
            at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
            at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
       InnerException: System.ComponentModel.Win32Exception
            ErrorCode=-2147467259
            Message="The target principal name is incorrect"
            NativeErrorCode=-2146893022
            InnerException: 
1个回答

20

显然,你需要传递一个空的SpnEndpointIdentity才能使其工作。

    Using con As New OfferingTap.OfferingTapClient( _ 
        New ServiceModel.InstanceContext(callback), "NetTcpBinding_IOfferingTap", _
        New ServiceModel.EndpointAddress(New Uri("net.tcp://qa1offerings:8190/"), _
        New ServiceModel.SpnEndpointIdentity("")))

1
浪费了4个小时才搞定这个...而这真的就是答案。 - Nelson Reis
1
谢谢。如果我能给你超过一个点,我会的。这是一个长期存在的问题,我终于因为你而解决了它! - dotnetengineer
你可以给这个问题点赞,这样其他人就会更容易找到它。 - Jonathan Allen
1
另一种对我有效的方法是用IP地址替换主机名。然后它似乎不关心身份验证。 - Chris Leonard
@ChrisLeonard 你救了我的一天!! - Sebastian Widz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接