2013-01-11 67 views
2

WCF例外 - 未提供客戶端證書。在ClientCredentials中指定客戶端證書。WCF例外 - 未提供客戶端證書

在閱讀了我在這個主題上找到的大部分內容後,嘗試了很多不同的選擇,我發現我沒有更多的頭髮可以拉出來,因此這篇文章也沒有。

我希望將SSL與自託管的WCF服務一起使用,將安全模式設置爲具有HTTP傳輸的TransportWithMessageCredential。我正在使用2臺開發機器並通過局域網進行測試。

如上所述,我已經仔細閱讀並仔細地關注了每個證明這一點的示例,但仍然有些問題與證書有關。

就證書而言,我嘗試了很多東西。

我所做的主要JIST是遵循什麼是 http://msdn.microsoft.com/en-us/library/ff647171.aspx

給我也用「如何:使用證書身份驗證和郵件安全性在WCF從Windows窗體調用」在 http://msdn.microsoft.com/en-us/library/ff648360.aspx 作爲基本指南。

我首先使用基於Http的basicHttpBinding測試服務和客戶端以驗證事情。

然後我對wsHttpBinding,SSL和Certificates進行了更改。

當我在客戶端開發PC上的「添加服務引用」,我收到一個錯誤如下:

  • 窗口標題爲 -

安全警報

的Visual Studio已經檢測到該網站的安全證書存在問題。

發放機構:頒發給RootCATest :TempCert 證書是有效的---

由公司頒發的安全證書不在非信任列表。這可能是可信的。

安全證書日期有效。

主機'TempCert'的安全證書與您嘗試查看的頁面的名稱不匹配。

  • 是否繼續? -

如果單擊「是」繼續,然後運行客戶端代碼,則會出現InvalidOperationException,並顯示以下消息。

「未提供客戶端證書。在ClientCredentials中指定客戶端證書。」

服務配置如下:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="ServiceBehavior"> 
        <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="true" /> 
        <serviceCredentials> 
         <serviceCertificate findValue="CN=TempCert" 
              storeLocation="LocalMachine" 
              storeName="My" /> 
        </serviceCredentials> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <bindings> 
      <wsHttpBinding> 
      <binding name="wsHttpEndpointBinding"> 
       <security mode="TransportWithMessageCredential"> 
       <message clientCredentialType="Certificate" /> 
       </security> 
      </binding> 
      </wsHttpBinding> 
     </bindings>  
     <services> 
      <service name="SBSWCFServiceHost.Operations" 
        behaviorConfiguration="ServiceBehavior"> 
       <endpoint name="wsHttpEndpoint" 
          address="" 
          binding="wsHttpBinding" 
          bindingConfiguration="wsHttpEndpointBinding" 
          contract="SBSWCFServiceHost.IOperations" > 
        <identity> 
         <dns value="localhost" /> 
        </identity> 
       </endpoint>       
       <endpoint name="mexHttpEndpoint" 
          address="mex" 
          binding="mexHttpsBinding" 
          contract="IMetadataExchange" > 
       </endpoint> 
       <host> 
        <baseAddresses> 
         <add baseAddress="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" /> 
        </baseAddresses> 
       </host> 
      </service> 
     </services> 
    </system.serviceModel> 
</configuration> 

客戶端的配置如下:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <behaviors> 
      <endpointBehaviors> 
       <behavior name="EndpointBehavior"> 
        <clientCredentials> 
         <clientCertificate storeLocation="LocalMachine" 
              storeName="My" 
              x509FindType="FindByThumbprint" 
              findValue="e4c87a961f796be6b6cab59c3760e43ffb6e941d"/> 
        </clientCredentials> 
       </behavior> 
      </endpointBehaviors> 
     </behaviors>  
     <bindings> 
      <wsHttpBinding> 
       <binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" 
        receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" 
        transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
        allowCookies="false"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <reliableSession ordered="true" inactivityTimeout="00:10:00" 
         enabled="false" /> 
        <security mode="TransportWithMessageCredential"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="Certificate" negotiateServiceCredential="true" 
          algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" 
       binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" 
       contract="SBSWCFService.IOperations" name="wsHttpEndpoint"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

以下是我執行任務的總結的基礎上,大量的內容帖子和文件。

  1. 創建自簽名CA證書在服務器上(名爲RootCATest),並把它放在本地計算機的受信任的根證書頒發機構的證書文件夾。

  2. 創建一個由服務器上的RootCATest證書(名爲TempCert)簽名並放置在本地計算機的個人證書文件夾中的證書。

  3. 導出TempCert證書和私鑰。

  4. 將TempCert .cer和.pvk文件複製到客戶機,並將TempCert證書導入到本地計算機的個人證書文件夾中。

  5. 執行ICalcs.exe [私鑰路徑] /授予「NT AUTHORITY \ NETWORK SERVICE」:R在服務器上,使用TempCert證書私鑰的路徑。

  6. 已執行的netsh的http添加的sslcert ipport = o.o.o.o:在服務器計算機

我相信我接近得到這方面的工作在8003 CERTHASH = [TempCert指紋]的appid = {[應用程序ID}]。

這似乎很明顯,該應用程序不滿意TempCert證書,但我還沒有能夠解決這個問題,而且幾乎卡住了。

有關給定配置中任何問題的任何幫助,我爲了放置正確的證書以及用於添加訪問權限和sslcert條目而遵循的步驟將不勝感激。

非常感謝。

經過一些進一步的實驗,我注意到了額外的行爲。是採取

操作步驟如下:

我刪除客戶端和服務器證書,並重建他們按照 .... codeproject.com/Articles/36683/9-simple-steps-to-enable -x-509-certificates-on-wcf

我使用netsh添加了新的sslcert。然後,我從服務器中導出客戶端證書,並將其導入到客戶端存儲中。

我用新的證書信息修改了服務app.config,並啓動了服務。

我修改了客戶端應用程序。配置如下:

<endpointBehaviors> 
    <behavior name="EndpointBehavior"> 
    <clientCredentials> 
     <clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="WCFClient" /> 
     <serviceCertificate> 
     <authentication certificateValidationMode="PeerTrust" /> 
     </serviceCertificate> 
    </clientCredentials> 
    </behavior> 
</endpointBehaviors> 

我更新了服務參考。更新程序再次發出安全警報。

我然後執行客戶端,並且接收到的這種錯誤:「沒有設置客戶端證書指定ClientCredentials客戶端證書。」

然後在「client = new WCFService.Client();」上設置一個斷點並檢查了「客戶端」實例。 client.ClientCredentials.ClientCertificate.Certificate = null的值。

我然後加入在以下代碼後 「客戶=新WCFService.Client();」:

X509Store store = new X509Store("My", StoreLocation.LocalMachine); 
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 
X509Certificate2Collection collection = (X509Certificate2Collection) store.Certificates; 
foreach (X509Certificate2 x509 in collection) 
{ 
if (x509.Thumbprint == "236D7D4AD95753B8F22D3781D61AACB45518E1B5") 
{ 
    client.ClientCredentials.ClientCertificate.SetCertificate(
     x509.SubjectName.Name, store.Location, StoreName.My); 
} 
} 

該代碼的執行之後,client.ClientCredentials.ClientCertificate.Certificate包含在證書。

然後執行「client.Open();」 ,以下內容引發異常。

底層連接已關閉:無法建立SSL/TLS安全通道的信任關係。 根據驗證程序,遠程證書無效。 無法建立具有權限的SSL/TLS安全通道的信任關係

如果有任何知道此處可能發生的事情的人可以對此有所瞭解,我將非常感激。

回答

1

最後一條錯誤消息表明您的服務器正在向客戶端請求客戶端證書(服務器必須要求),並且客戶端正在提供證書,但服務器無法確定客戶端證書是否有效根據服務器機器上可用的信息。

由於您使用的是自簽名證書(不是CA頒發的證書),因此您需要告訴服務器如何驗證客戶端證書。您可能需要在服務器的My/LocalMachine/Trusted People證書存儲區中安裝客戶端證書,以便WCF的默認證書驗證可以找到它們,或者在服務器上實現您自己的自定義客戶端證書驗證程序。 (請參閱WebHttpBinding.Credentials.ClientCertificate.Authentication.CertificateValidationModeWebHttpBinding.Credentials.ClientCertificate.Authentication.CustomCertificateValidator

0

我注意到在您的endpoint定義中,您沒有引用您定義的behavior。它看起來好像你正在通過一些代碼手動執行相同的操作。只需在配置中進行配線可能會更簡單。

我希望您的端點看(更多)這樣的:「不提供客戶端證書ClientCredentials指定客戶端證書」

 <endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" 
      binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" 
      contract="SBSWCFService.IOperations" name="wsHttpEndpoint" 
      behaviorConfiguration="EndpointBehavior"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 

這是解決辦法,當我得到的錯誤。