C# WCF WSHttpBinding SOAP 安全协商失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9092688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:52:53  来源:igfitidea点击:

WCF WSHttpBinding SOAP Security Negotiation Failed

c#asp.net.netvb.netwcf

提问by naacal

I've got a fairly simple WCF self-hosted service using the WSHttpBinding that just refuses to work. If service and client runs on the same machine there's no problem, but as soon as I move the service to the window-server 2008 the client fails the communication attempts with

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

例外

[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 中的标识。"}

Since it's a self-hosted service I suppose I need to specify the UserPrincipalName, but no matter what I try for that property it just won't work.

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

  • domain\username
  • domain@username
  • host/localhost
  • host/hvw-svr-01
  • ... and so on
  • 域\用户名
  • 域@用户名
  • 主机/本地主机
  • 主机/hvw-svr-01
  • ... 等等

Tried it with different user accounts aswell, including the built-in Administrator. If I try BasicHttpBinding instead of WSHttpBinding everything works as expected. I read tons of articles about that problem on google (and stackoverflow) but I still cannot figure what the problem is and how to specify that identity.

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

Edit: Service App.Config

编辑:服务 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>

Edit: The Client itself is basically just this code fragment

编辑:客户端本身基本上就是这个代码片段

        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
        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

采纳答案by Rajesh

To enable the Negotiate process to select the Kerberos protocol for network authentication, the client application must provide an SPN, a user principal name (UPN), or a NetBIOS account name as the target name. If the client application does not provide a target name, the Negotiate process cannot use the Kerberos protocol. If the Negotiate process cannot use the Kerberos protocol, the Negotiate process selects the NTLM protocol.

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

In cross-domain, kerberos has to be used. Since service is running as local system account, a SPN identity has to be used on the client side for the target name.

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

For more informaiton, read http://support.microsoft.com/kb/929650

有关更多信息,请阅读http://support.microsoft.com/kb/929650

Hope this helps!

希望这可以帮助!

回答by yg abhi

You can opt for basic HTTP binding if WSHttpBindingis not an actual requisite. :)

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

Basic HTTP eliminates the <identiy>tag so UPN and SPN problems wouldn't occur.

基本 HTTP 消除了<identiy>标记,因此不会出现 UPN 和 SPN 问题。

回答by jimmybao

I had the same issue and I tried almost all the settings in web.config and in the IIS server. And the best way for me is to set UPN when creating the client:

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

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