2011-08-17 74 views
0

我正在尋找一個明確的答案,以確定我是否支持或不支持。在WCF和證書認證中流式傳輸MTOM附件

基本上,我使用WCF流式傳輸大型MTOM附件(200 Mb),這工作得很好。該服務的安全要求是使用HTTPS和基於證書的身份驗證。我可以通過HTTPS運行服務而沒有任何問題,但是一旦我將IIS設置爲「接受客戶端證書」或「需要客戶端證書」(代碼中沒有更改),就會引發以下錯誤(但只有在附件完成了80 MB左右):

The socket connection was aborted. 
This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. 
Local socket timeout was '00:30:00'. 

我發現了一些資源,對不起,現在不能找到他們,這表明該故障可能與一個事實,即傳入的消息或者不能進行數字簽名,或由於驗證到消息內容的流式性質。我相信該服務將不得不散列整個消息內容來驗證證書,但這不能實現,因爲部分消息正在傳輸,而驗證嘗試發生。

我已經建立的消息合同,使得體爲單流元件和其它元件都包含在報頭內:

<MessageContract()> 
Public Class StreamAttachmentRequest 

    <MessageHeader(MustUnderstand:=True)> 
    Public Property AttachmentName As String 

    <MessageBodyMember(Order:=1)> 
    Public Property Attachment As Stream 

End Class 

服務配置看起來如下:

<system.serviceModel> 

<!-- BINDING --> 
<bindings> 
<basicHttpBinding> 
    <binding name="TestCaseBasicBinding" 
      messageEncoding="Mtom" 
      transferMode="StreamedRequest" 
      maxReceivedMessageSize="2147483647" 
      closeTimeout="00:30:00" 
      openTimeout="00:30:00" 
      receiveTimeout="00:30:00" 
      sendTimeout="00:30:00"> 
    <security mode="Transport"> 
     <transport clientCredentialType="None"></transport> 
    </security> 
    <readerQuotas maxDepth="32" 
         maxStringContentLength="8192" 
         maxArrayLength="16384" 
         maxBytesPerRead="4096" 
         maxNameTableCharCount="16384" /> 
    </binding> 
</basicHttpBinding> 
</bindings> 

<!-- BEHAVIORS --> 
<behaviors> 
    <serviceBehaviors> 

    <!-- TEST CASE SECURE BEHAVIOR --> 
    <behavior name="TestCaseSecureBehavior"> 
     <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" /> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
     <serviceCredentials> 
     <serviceCertificate 
      storeLocation="LocalMachine" 
      storeName="My" 
      findValue="DistinguishedNameOfCert" 
      x509FindType="FindBySubjectDistinguishedName" /> 
     <clientCertificate> 
      <authentication certificateValidationMode="ChainTrust"/> 
     </clientCertificate> 
     </serviceCredentials> 
    </behavior> 

    </serviceBehaviors> 
</behaviors> 

<!-- SERVICES --> 
<services> 
    <service name="StreamingMutualAuthTestCase.Web.Service.TestCaseServiceImplementation" 
      behaviorConfiguration="TestCaseSecureBehavior"> 
    <!-- SERVICE --> 
    <endpoint address="" 
       binding="basicHttpBinding" 
       bindingConfiguration="TestCaseBasicBinding" 
       contract="StreamingMutualAuthTestCase.Web.Service.ITestCaseService" /> 

    <endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" /> 

    </service> 
</services>  

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 

客戶端配置是這樣的:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_ITestCaseService" closeTimeout="00:30:00" 
       openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00" 
       maxReceivedMessageSize="2147483647" messageEncoding="Mtom" 
       transferMode="Streamed"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <security mode="Transport"> 
        <transport clientCredentialType="Certificate" realm="" /> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 

    <!-- BEHAVIORS --> 
    <behaviors> 
    <endpointBehaviors> 
     <behavior name="SecureClientBehavior"> 
     <clientCredentials> 
      <clientCertificate 
      storeLocation="LocalMachine" 
      storeName="My" 
      findValue="DistinguishedNameOfCert" 
      x509FindType="FindBySubjectDistinguishedName"/> 
      <serviceCertificate> 
      <authentication certificateValidationMode="ChainTrust"/> 
      </serviceCertificate> 
     </clientCredentials> 
     </behavior> 
    </endpointBehaviors> 
    </behaviors> 

    <client> 
     <endpoint address="https://test7/TestCaseService/TestCaseService.svc" 
        binding="basicHttpBinding" 
        bindingConfiguration="BasicHttpBinding_ITestCaseService" 
        contract="TestCaseService.ITestCaseService" 
        name="BasicHttpBinding_ITestCaseService" 
        behaviorConfiguration="SecureClientBehavior"/> 
    </client> 
</system.serviceModel> 

再次,這將工作得很好,直到我將IIS客戶端證書設置爲接受或要求。

此外,還有一個413錯誤在IIS日誌...

2011-08-18 15:00:06 W3SVC1 10.39.8.111 POST /TestCaseService/TestCaseService.svc - 443 - 10.75.13.81 - - - test7 413 0 0 

我已經設計了我的文件上傳服務來解決這些問題的頂部的認證服務;但我真的很想知道我想要做的是「可以做到」還是不做。

由於一噸 - 帕特里克

+0

你甚至可以查看HTTP代碼413的含義嗎?請求過大 - http://www.checkupdown.com/status/E413.html – x0n

+0

完整源代碼示例工作的最終解決方案? – Kiquenet

+0

@Kiquenet我最終重構了我在問題中提到的解決方案。我編寫了一個特定的身份驗證令牌服務,該服務返回了一個即將到來的令牌,並隨後發送請求。 –

回答

1

如果你想打開客戶端證書在IIS中,您必須對您的服務(和客戶端)做相同的:

<security mode="Transport"> 
    <transport clientCredentialType="Certificate" /> 
</security> 

客戶必須向提供證書代理:

yourProxy.ClientCredentials.ClientCertificate.SetCertificate(...); 

而且您的服務器,以便客戶端證書必須由證書頒發機構頒發或者由服務器信任必須信任這些證書或者必須安裝到LocalMachine \ Trusted people直接存儲在服務器上。

WCF端點不支持「接受客戶端證書」 - 您必須使用客戶端證書或不使用客戶端證書。

+0

感謝Ladislav的信息,我已經能夠使用證書認證工作,所以我知道這部分工作正常。無論我將客戶端憑證類型設置爲無還是證書都無關緊要。 –