Reputation: 11
I have a simple WCF service configured for with transport security and Certificate client credentials. I plug a custom certificate validator to it, and throws a FaultException. My probkemn is the esception message does not reach the client : i only receive a MessageSecurityException without any Fault... If i turn my service in net.tcp (self-hosted), i the receive a CommunicationExcetion, with no Fault either.
Here is a part of 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>
and my Validator :
public class CPSValidator : System.IdentityModel.Selectors.X509CertificateValidator
{
public override void Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
{
throw new FaultException("Certificate is not from a trusted issuer");
}
}
Any idea ?
Thanks in advance for any help !
Upvotes: 0
Views: 2330
Reputation: 11
As Yahia and Pablo answered, certificate validation does not happens at service level. Therefore, FaultException cannot reach the client. But this is true only because i am using the transport security mode. In order to send message back to the client i had to change my security mode from Transport to TransportWithMessageCredentials, like this :
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
This way, the certificate validation is done at service level, so that an error message can be sent to the client throught a faultException.
Upvotes: 1
Reputation: 2096
Have you tried turning on WCF diagnostics on the server to catch issues in the WCF pipeline prior to the call getting to the service itself?
<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"/>
Upvotes: 0
Reputation: 3959
As far as I know, any exception that you throw in a validator never reaches the client. The client always receives a MessageSecurityException. Only the exceptions that happens at service level (in the service implementation) and are mapped to a FaultContract are correctly sent to the client.
Regards Pablo.
Upvotes: 1