我有一个相当简单的 WCF 自托管服务,它使用 WSHttpBinding 只是拒绝工作。如果服务和客户端在同一台机器上运行,则没有问题,但是一旦我将服务移动到窗口服务器 2008,客户端就无法通过
EXCEPTION
[System.ServiceModel.Security.SecurityNegotiationException] {"SOAP security negotiation with 'http://hvw-svr-01/SIT' for target 'http://hvw-svr-01/SIT' failed. See inner exception for more details."}
INNER EXCEPTION
[System.ComponentModel.Win32Exception] {"The Security Support Provider Interface (SSPI) negotiation failed. The server may not be running in an account with identity 'host/hvw-svr-01'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server."}
由于它是一项自托管服务,我想我需要指定 UserPrincipalName,但无论我为该属性尝试什么,它都不会起作用。
- 域名\用户名
- 域@用户名
- 主机/本地主机
- 主机/hvw-svr-01
- ...等等
还尝试了不同的用户帐户,包括内置管理员。如果我尝试使用 BasicHttpBinding 而不是 WSHttpBinding,一切都会按预期工作。我在 google(和 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>
编辑:客户端本身基本上就是这个代码片段
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 协议(protocol),客户端应用程序必须提供 SPN、用户主体名称 (UPN) 或 NetBIOS 帐户名称作为目标名称。如果客户端应用程序不提供目标名称,则协商过程无法使用 Kerberos 协议(protocol)。如果Negotiate进程不能使用Kerberos协议(protocol),Negotiate进程会选择NTLM协议(protocol)。
在跨域中,必须使用kerberos。由于服务作为本地系统帐户运行,因此必须在客户端使用 SPN 身份作为目标名称。
有关更多信息,请阅读 http://support.microsoft.com/kb/929650
希望这对您有所帮助!
关于c# - WCF WSHttpBinding SOAP 安全协商失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9092688/