【问题标题】:WCF WSHttpBinding SOAP Security Negotiation FailedWCF WSHttpBinding SOAP 安全协商失败
【发布时间】:2012-02-01 08:12:08
【问题描述】:

我有一个相当简单的 WCF 自托管服务,它使用 WSHttpBinding 只是拒绝工作。如果服务和客户端在同一台机器上运行,则没有问题,但是一旦我将服务移动到 window-server 2008,客户端的通信尝试就会失败

例外

[System.ServiceModel.Security.SecurityNegotiationException] {"目标 'http://hvw-svr-01/SIT' 的 SOAP 安全协商失败。请参阅内部更多细节的例外。"}

内部异常

[System.ComponentModel.Win32Exception] {“安全支持提供程序接口 (SSPI) 协商失败。服务器可能未在身份为 'host/hvw-svr-01' 的帐户中运行。如果服务器在服务帐户(例如网络服务),将帐户的 ServicePrincipalName 指定为服务器的 EndpointAddress 中的身份。如果服务器在用户帐户中运行,请将帐户的 UserPrincipalName 指定为服务器的 EndpointAddress 中的身份。"}

由于它是自托管服务,我想我需要指定 UserPrincipalName,但无论我为该属性尝试什么,它都不起作用。

  • 域\用户名
  • 域@用户名
  • 主机/本地主机
  • 主机/hvw-svr-01
  • ...等等

还尝试了不同的用户帐户,包括内置的管理员。如果我尝试 BasicHttpBinding 而不是 WSHttpBinding 一切都按预期工作。我在 google(和 stackoverflow)上阅读了大量关于该问题的文章,但我仍然无法弄清楚问题是什么以及如何指定该身份。

编辑:Service 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

【问题讨论】:

  • 您可以发布您用于托管服务的配置吗?
  • 如果您从配置中完全删除 idenity 部分,它会起作用吗?
  • 不行,已经试过了(在stackoverflow上的某处阅读)
  • 机器是否在同一个域中?
  • 您也可以发布客户端的配置,以便我们了解客户端的期望吗?

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


【解决方案1】:

要使协商进程能够选择 Kerberos 协议进行网络身份验证,客户端应用程序必须提供 SPN、用户主体名称 (UPN) 或 NetBIOS 帐户名称作为目标名称。如果客户端应用程序不提供目标名称,则协商进程无法使用 Kerberos 协议。如果协商进程无法使用 Kerberos 协议,则协商进程选择 NTLM 协议。

在跨域中,必须使用 kerberos。由于服务作为本地系统帐户运行,因此必须在客户端使用 SPN 身份作为目标名称。

欲了解更多信息,请阅读http://support.microsoft.com/kb/929650

希望这会有所帮助!

【讨论】:

  • 谢谢你确实帮了很多忙。但是为什么我的情况正好是跨域的呢?自托管的 WCF 应用程序在属于我们域成员的帐户下运行(Windows 服务器和客户端计算机)。我尝试在客户端配置中提供 UPN,它确实有效,所以这绝对是问题所在……但为什么我必须这样做?如果没有提供,我希望 WCF 默认提供当前登录用户帐户的 UPN。
  • 非常有帮助的答案。我有一个类似的问题。由于某种原因,使用 IP 地址调用 WCF 服务允许 NTLM 并且身份验证成功。使用完全限定的域名身份验证失败并显示“soap 安全协商失败......等”,因为我没有提供 UPN(我不知道如何通过配置,因为端点是联合场景中的颁发者端点,我可以't see how to add the UPN to the issuer binding config)
  • @naacl - 你有没有对这个话题有所启发?我自己很难了解我的同域用户帐户情况
  • 哦,我刚刚意识到我的 DNS 主机名不正确。该主机可以通过我使用的主机名访问,但它的默认名称,即它所呈现的名称,是不同的。使用那个正确的允许我跳过明确的 spn 业务。
【解决方案2】:

如果WSHttpBinding 不是必需的,您可以选择基本的 HTTP 绑定。 :)

基本 HTTP 消除了 &lt;identiy&gt; 标记,因此不会出现 UPN 和 SPN 问题。

【讨论】:

  • 如何选择基本的 HTTP 绑定?
  • 嗨,通过在客户端用 basicHttpBinding 替换绑定 wsHttpBinding 并在服务端使用 basicHttpBinding 公开端点
【解决方案3】:

我遇到了同样的问题,我尝试了 web.config 和 IIS 服务器中的几乎所有设置。 而对我来说最好的方法是在创建客户端时设置UPN:

EndpointAddress endptAddress = 
               new EndpointAddress(
                  new Uri(your URL),
                  EndpointIdentity.CreateUpnIdentity("domain\username"));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-29
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多