c# - WCF WSHttpBinding SOAP 安全协商失败

标签 c# asp.net .net vb.net wcf

我有一个相当简单的 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/

相关文章:

c# - 使用 System.Diagnostics 进行简单调试和日志记录

c# - MVC Razor 按钮单击事件传递参数

c# - 以横向模式打印当前事件窗口

c# - 使用 .NET 在服务器端生成 Flash 对象

asp.net - 如何在 .NET v3.5 中创建 ASP.NET Web 窗体应用程序

c# - 如何从文本框中删除CSS?

asp.net - ASP 菜单未显示

c# - 未找到 DBSet<entity> 类( Entity Framework 加载错误的 DLL?)

c# - 应用程序在 Windows 启动时运行时找不到 app.config 文件

c# - kentico cms中自定义字段的级联下拉列表