2011-08-17 38 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的信息,我已经能够使用证书认证工作,所以我知道这部分工作正常。无论我将客户端凭证类型设置为无还是证书都无关紧要。 –