2009-08-05 77 views
3

我們有一個相當大的應用程序,我的團隊正在開發包含大量基於WCF NetTCP的服務。該系統將運行的Windows服務不會是本地帳戶,而是標準域用戶(在託管該服務的服務器上具有管理員權限)。在連接測試中,我遇到了一個SSPI調用失敗的問題。基於研究的幾個小時這導致我失望了我的失蹤從我的客戶端配置以下行的路徑:WCF代理和userPrincipalName

<identity> 
    <userPrincipalName value="MACHINE\user" /> 
</identity> 

使用,這是我不使用VS或SvcUtil工具生成客戶端的問題/代理此服務 - 正在使用的代理完全用代碼編寫,它們繼承System.ServiceModel.ClientBase。我相信選擇此選項的最初原因是我們可以使用完全相同的DataMember對象來傳遞圍欄兩側的服務 - 第三方組不需要連接到我們的服務,所以這不是問題。

有沒有人知道我在客戶端(代碼或通過配置)設置userPrincipalName的方式,當我沒有在標準system.serviceModel配置節中指定端點?

這裏是我的客戶端的web.config看起來像以供參考:

<system.serviceModel> 
    <diagnostics> 
     <messageLogging logEntireMessage="true" logMalformedMessages="true" 
     logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" /> 
    </diagnostics> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="includeExceptions"> 
       <serviceDebug includeExceptionDetailInFaults="true"/> 
       <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <netTcpBinding> 
      <binding name="NetTcpBinding_Default" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="Infinite" sendTimeout="01:00:00" portSharingEnabled="true" transferMode="Buffered" maxReceivedMessageSize="2147483647"> 
       <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
       <security mode="Transport"> 
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/> 
       </security> 
      </binding> 
     </netTcpBinding> 
    </bindings> 

</system.serviceModel> 

回答

6

手動創建代理並不妨礙您將配置放置在配置文件中;你只需要在你的ClientBase派生的代理類中公開正確的構造函數重載,該代理類委託給ClientBase中的right constructor,它使用在配置中查找的端點名稱。這就是說,你當然可以通過代碼填充端點標識,只需要創建一個正確的EndpointIdentity派生類並將其附加到實例化代理類時使用的EndpointAddress對象上。類似這樣的:

EndpointIdentity epid = EndpointIdentity.CreateUpnIdentity("[email protected]"); 
EndpointAddress epaddr = new EndpointAddress(uri, epid); 

MyClient client = new MyClient(epaddr); 
+0

Ash的第一條評論讓我開始了一條在托馬斯的幫助下完成的路徑,現在一切正常。 作爲一個方面說明,要創建一個新的EndpointAddress,您必須指定一個Uri,EndpointIdentity和一個AddressHeader對象以使其正常工作。他們的API設置有點混亂(尤其是如果你沒有正確使用base.New,會出現一些模糊的錯誤),但是都告訴它它的功能。 感謝您的幫助! – RubyHaus 2009-08-06 18:14:00

+2

對於其他人在看這個答案,仍然有問題,我需要使用「DOMAIN \用戶」,仍然沒有工作。我發現我必須使用「[email protected]」(或您的完全合格的Active Directory域名。 – Jim 2012-10-02 16:39:02

1

雖然我可能不會直接回答你的問題,使用相同的數據成員的圍欄上的兩側,你不」您需要手動創建代理。你要做的就是您在使用SvcUtil工具生成你的代理,你在

svcutil http://localhost/service/service.svc /r:AssemblyThatHasDataMembers.dll /out:ServiceProxy.cs 

這樣,數據成員類型不是在你的ServiceProxy.cs反覆有你的數據成員作爲該dll/R通過文件。您可以通過傳遞wsdl/xsd(真正的合同第一種方法),使用/ ct等自定義收集類型等來廣泛定製此功能。

這將爲您節省許多手工製作代理的時間,同時避免類似問題以上你可能會遇到,因爲一切都成爲股票標準。