naa*_*cal 4 .net c# vb.net asp.net wcf
我有一个相当简单的 WCF 自托管服务,它使用 WSHttpBinding 只是拒绝工作。如果服务和客户端在同一台机器上运行,则没有问题,但是一旦我将服务移动到窗口服务器 2008,客户端就会尝试与
例外
[System.ServiceModel.Security.SecurityNegotiationException] {"SOAP 安全协商与目标 'http://hvw-svr-01/SIT' 的目标 'http://hvw-svr-01/SIT' 失败。有关更多信息,请参阅内部异常细节。”}
内部异常
[System.ComponentModel.Win32Exception] {"安全支持提供程序接口 (SSPI) 协商失败。服务器可能未在身份为“host/hvw-svr-01”的帐户中运行。如果服务器在服务帐户中运行(例如网络服务),将帐户的 ServicePrincipalName 指定为服务器的 EndpointAddress 中的标识。如果服务器在用户帐户中运行,请指定帐户的 UserPrincipalName 作为服务器的 EndpointAddress 中的标识。"}
由于它是一个自托管服务,我想我需要指定 UserPrincipalName,但无论我对该属性进行什么尝试,它都不起作用。
也尝试使用不同的用户帐户,包括内置的管理员。如果我尝试 BasicHttpBinding 而不是 WSHttpBinding 一切都按预期工作。我在谷歌(和stackoverflow)上阅读了大量关于该问题的文章,但我仍然无法弄清楚问题是什么以及如何指定该身份。
编辑:服务 App.Config
<system.serviceModel>
<services>
<service name="SIT.Communication.Gate">
<host>
<baseAddresses>
<add baseAddress="http://localhost:2323/SIT" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="SIT.Core.IGate">
<identity>
<dns value="localhost"/>
<userPrincipalName value="XZDom\DGrain"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
Run Code Online (Sandbox Code Playgroud)
编辑:客户端本身基本上就是这个代码片段
Run Code Online (Sandbox Code Playgroud)ChannelFactory<IGate> sitFactory = new ChannelFactory<IGate>(new WSHttpBinding(), new EndpointAddress("http://hvw-svr-01:2323/SIT")); IGate sitProxy = sitFactory.CreateChannel(); bool pong = sitProxy.Ping(); <------ throws exception
要使协商进程能够选择 Kerberos 协议进行网络身份验证,客户端应用程序必须提供 SPN、用户主体名称 (UPN) 或 NetBIOS 帐户名称作为目标名称。如果客户端应用程序不提供目标名称,则协商进程无法使用 Kerberos 协议。如果协商进程无法使用 Kerberos 协议,协商进程将选择 NTLM 协议。
在跨域中,必须使用 kerberos。由于服务作为本地系统帐户运行,因此必须在客户端使用 SPN 身份作为目标名称。
有关更多信息,请阅读http://support.microsoft.com/kb/929650
希望这可以帮助!