WCF中的流式MTOM附件和证书身份验证
我正在寻找一个明确的答案,以确定我正在尝试做的事情是否得到支持 基本上,我使用WCF来流式传输大型MTOM附件(200 Mb),这非常好用。该服务的安全要求是使用HTTPS和基于证书的身份验证。我可以通过HTTPS运行服务,没有任何问题,但是一旦我将IIS设置为“接受客户端证书”或“需要客户端证书”(代码中没有更改),就会抛出以下错误(但只有当附件超过大约80MB时): 我发现了一些资源,很抱歉现在找不到,这表明失败可能与以下事实有关:由于消息内容的流性质,传入消息无法进行数字签名或验证。我相信该服务必须散列整个消息内容以验证证书,但这无法实现,因为在尝试进行验证时,部分消息正在传输中 我已经设置了消息约定,以便主体是单个流元素,其他元素包含在头中:WCF中的流式MTOM附件和证书身份验证,wcf,streaming,certificate,x509,mtom,Wcf,Streaming,Certificate,X509,Mtom,我正在寻找一个明确的答案,以确定我正在尝试做的事情是否得到支持 基本上,我使用WCF来流式传输大型MTOM附件(200 Mb),这非常好用。该服务的安全要求是使用HTTPS和基于证书的身份验证。我可以通过HTTPS运行服务,没有任何问题,但是一旦我将IIS设置为“接受客户端证书”或“需要客户端证书”(代码中没有更改),就会抛出以下错误(但只有当附件超过大约80MB时): 我发现了一些资源,很抱歉现在找不到,这表明失败可能与以下事实有关:由于消息内容的流性质,传入消息无法进行数字签名或验证。我相信
<MessageContract()>
Public Class StreamAttachmentRequest
<MessageHeader(MustUnderstand:=True)>
Public Property AttachmentName As String
<MessageBodyMember(Order:=1)>
Public Property Attachment As Stream
End Class
我已经在我的文件上传服务之上设计了一个身份验证服务来解决这个问题;但我真的很想知道我想做的是“做得到”还是“做不到”
非常感谢,如果您想在IIS中打开客户端证书,您必须为您的服务(和客户端)执行相同的操作: 此外,服务器必须信任这些证书,因此客户端证书必须由服务器信任的证书颁发机构颁发,或者必须直接安装到服务器上的LocalMachine\trusted people存储中
WCF端点不支持“接受客户端证书”-您必须使用或不使用客户端证书。感谢Ladislav提供的信息,我已经能够让服务使用证书身份验证,因此我知道该部分正在工作。不管我是将客户端凭据类型设置为“无”还是“证书”,你们都查过HTTP代码413的含义了吗?请求太大-是否有完整源代码示例有效的最终解决方案?@Kiquenet我最终按照问题中提到的解决方案进行了重构。我编写了一个特定的身份验证令牌服务,该服务返回一个即将到期的令牌,以便与后续请求一起传递。
<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>
2011-08-18 15:00:06 W3SVC1 10.39.8.111 POST /TestCaseService/TestCaseService.svc - 443 - 10.75.13.81 - - - test7 413 0 0
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
yourProxy.ClientCredentials.ClientCertificate.SetCertificate(...);