C# WCF证书自定义验证-向客户端发送异常消息

C# WCF证书自定义验证-向客户端发送异常消息,c#,wcf,wcf-security,C#,Wcf,Wcf Security,我有一个简单的WCF服务,配置为具有传输安全性和证书客户端凭据。 我将自定义证书验证器插入其中,并抛出一个FaultException。 我的问题是esception消息没有到达客户端:我只收到MessageSecurityException,没有任何错误。。。 如果我在net.tcp(自托管)中打开我的服务,我将收到一个CommunicationExcetion,并且没有任何错误 以下是my web.config的一部分: <system.serviceModel> <

我有一个简单的WCF服务,配置为具有传输安全性和证书客户端凭据。 我将自定义证书验证器插入其中,并抛出一个FaultException。 我的问题是esception消息没有到达客户端:我只收到MessageSecurityException,没有任何错误。。。 如果我在net.tcp(自托管)中打开我的服务,我将收到一个CommunicationExcetion,并且没有任何错误

以下是my web.config的一部分:

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding" messageEncoding="Text">
          <reliableSession enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="SecureService.Server.ChunkStreamService">
        <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" behaviorConfiguration="myBehavior" name="wsHttpEndPoint" contract="SecureService.Server.IChunkStreamService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="myBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <clientCertificate>
              <authentication  customCertificateValidatorType="SecureService.Server.CPSValidator, SecureService.Server" certificateValidationMode="Custom" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
有什么想法吗


提前感谢您的帮助

据我所知,您在验证器中抛出的任何异常都不会到达客户端。客户端始终收到MessageSecurityException。只有在服务级别(在服务实现中)发生并映射到FaultContract的异常才会正确发送到客户端

问候
Pablo.

在呼叫到达服务本身之前,您是否尝试在服务器上打开WCF诊断以捕获WCF管道中的问题

<system.diagnostics>
<sources>
  <source name="System.ServiceModel" switchValue="Verbose" propagateActivity="true">
    <listeners>
      <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="log.evtlog"  />
    </listeners>
  </source>
</sources>
<trace autoflush="true"/>


正如Yahia和Pablo回答的那样,证书验证不会在服务级别进行。因此,FaultException无法到达客户端。但这是真的,因为我使用的是交通安全模式。为了将消息发送回客户端,我必须将安全模式从Transport更改为TransportWithMessageCredentials,如下所示:

<security mode="TransportWithMessageCredential">
  <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
  <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>


通过这种方式,证书验证在服务级别完成,因此可以通过faultException向客户端发送错误消息。

如果证书验证步骤发生在不同的层上-远远低于WCF的故障处理机制,它发生在SSL级别上,在本例中直接位于TCP/IP之上……但我在msdn上读到(显然不起作用)“注意:要将身份验证错误返回给客户端,请在Validate方法中抛出FaultException。”()我用用户名验证和自定义验证器做了一个测试:发送FaultException允许在客户端检索消息。。。与我的证书验证不同的是,我使用TransportWithMessageCredential:这可能是关键点吗?类似于:用户名验证发生在服务级别,而证书验证发生在较低级别(因此在网络级别,它不知道任何自定义异常)…好的:那么有没有一种方法可以使用MessageCredential和证书身份验证进行传输?它会降低安全级别吗?因此,无法解释客户端发生了什么?(过期/吊销/不受信任…证书,或其他未知问题)不幸的是,这没有给我更多关于发生了什么以及为什么我的错误消息没有到达客户端的信息。似乎亚希亚和巴勃罗说的合同只是在服务水平上是对的。
<security mode="TransportWithMessageCredential">
  <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
  <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>