2012-02-01 371 views
3

我有一個相當簡單的WCF自託管服務,使用只拒絕工作的WSHttpBinding。如果服務端和客戶端在同一臺機器上運行沒有任何問題,但只要我移動服務至2008年窗口服務器與客戶端WCF WSHttpBinding SOAP安全協商失敗

EXCEPTION

[System.ServiceModel失敗的通信嘗試。 Security.SecurityNegotiationException] {「目標爲'http:// hvw-svr-01/SIT'的SOAP安全協商爲'http:// hvw-svr-01/SIT'失敗,詳情請參閱內部異常。」}

INNER EXCEPTION

[System.ComponentModel.Win32Exception] {「The Security支持提供程序接口(SSPI)協商失敗。服務器可能未運行在身份爲「host/hvw-svr-01」的帳戶中。如果服務器在服務帳戶中運行(例如,網絡服務),請將該帳戶的ServicePrincipalName指定爲該服務器的EndpointAddress中的標識。如果服務器中的用戶帳戶運行,指定帳戶的UserPrincipalName作爲的EndpointAddress服務器的身份。「}

因爲它是一個自託管服務,我想我需要指定的UserPrincipalName,但沒有不管我怎麼努力爲財產,它只是將無法正常工作。

  • 域\用戶名
  • 域@用戶名
  • 主機/本地主機
  • 主機/ HVW-SVR-01
  • ...等等

不同用戶嘗試它佔藏漢,包括內置的管理員。如果我嘗試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> 

編輯:客戶端本身基本上是這樣的代碼片段

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

您可以發佈用於託管服務的配置嗎? – 2012-02-01 08:19:00

+0

如果您從配置中完全刪除'idenity'部分,它是否工作? – 2012-02-01 09:15:50

+0

Nope不起作用,已經試過了(在stackoverflow上讀取某處) – naacal 2012-02-01 09:18:56

回答

4

爲了使協商過程選擇Kerberos協議用於網絡認證,客戶端應用程序必須提供SPN,a用戶主體名稱(UPN)或NetBIOS帳戶名稱作爲目標名稱。如果客戶端應用程序未提供目標名稱,則協商進程將無法使用Kerberos協議。如果協商進程不能使用Kerberos協議,則協商進程將選擇NTLM協議。

在跨域中,必須使用kerberos。由於服務以本地系統帳戶運行,因此必須在客戶端使用SPN標識作爲目標名稱。

更多情報,請閱讀http://support.microsoft.com/kb/929650

希望這有助於!

+2

謝謝,幫助確實很多。但爲什麼我的情況完全跨域?自託管的WCF應用程序在屬於我們域的成員帳戶(windows-server&client機器以及)下運行。我嘗試在客戶端配置中提供UPN,並且確實起作用,所以這肯定是問題......但爲什麼我必須這樣做呢?如果沒有人提供,我希望WCF提供當前登錄的用戶帳戶的UPN。 – naacal 2012-02-01 12:49:34

+1

非常有幫助的答案。我有一個類似的問題。出於某種原因使用IP地址調用WCF服務允許NTLM和身份驗證成功。因爲我沒有提供UPN(我不知道如何通過配置,因爲端點是聯合場景中的發佈端點,我可以使用完全合格的域名身份驗證失敗沒有看到如何將UPN添加到發行者綁定配置中) – Sentinel 2012-03-16 09:37:13

+0

@naacl - 您是否曾經在這個主題上獲得啓發?我努力瞭解自己的所有同域用戶帳戶情況 – 2014-05-02 16:43:27

3

如果WSHttpBinding不是真正的必要條件,您可以選擇基本的HTTP綁定。 :)

基本HTTP消除了<identiy>標記,因此不會發生UPN和SPN問題。

+3

如何選擇基本的HTTP綁定? – 2013-02-20 23:23:32

+1

嗨,通過替換您的綁定wsHttpBinding在客戶端的basicHttpBinding和暴露在服務端的basicHttpBinding端點 – 2016-04-12 15:15:52

1

我有同樣的問題,我幾乎嘗試了web.config和IIS服務器中的所有設置。 對我來說最好的辦法是在創建客戶端時設置UPN:

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