Reputation: 1
To create a .Net client that would use WCF to consume a web service that implements WS-SECURTY, I created a CustomBinding to which I added three elements:
With this CustomBinding and an EndpointAddress I instantiated the client, and then established the client and server certificates using the following code:
MyClient.ClientCredentials.ClientCertificate.Certificate = myCertificate MyClient.ClientCredentials.ServiceCertificate.DefaultCertificate = serverCertificate
The problem I have now is that I need to consume services that are part of a network with more than 90 endpoints, each with its own certificate, so knowing the service certificate in advance is impossible, or impractical. The lack of security of this approach would not be a problem, because the certificates used by the services must comply with certain rules and would be validated on the client, but WCF always throws me an error because I have not set the server certificate.
Is there no way to consume a web service with WS-SECURTY with WCF without knowing the public key of the service certificate beforehand?
Thank you for your answers.
I have tried setting the server certificate validation mode to "None" using the following code, but it has not worked:
MyClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None
I have also tried setting a CustomCertificateValidator with the following code, but it still asks for the server certificate:
MyClient.ClientCredentials.ServiceCertificate.Authentication.CustomCertificateValidator = New CustomCertificateValidator
I have also tried setting any certificate for the server and validating the actual certificate in the CustomCertificateValidator, but the certificate I receive in the validator is the same certificate I configured and not the actual certificate coming from the server.
I would like to know if there is any way, using WCF, to consume this type of services without knowing the service certificate.
Upvotes: 0
Views: 43
Reputation: 1
As I have said in some comments, WCF always requires that the server be set with a certificate, because from that certificate it determines the identity of the server and rules out MITM attacks. The solution I found was to use any certificate for the server (it can be the same certificate used for the client) and modify the client's behavior so that it accepts the server's identity without using that certificate, accepts non-secure responses and removes any security headers in incoming messages (to prevent WCF from rejecting them, because they will be signed with a different certificate). The behavior modifications would be:
Upvotes: 0
Reputation: 518
You can use the X509CertificateValidator to specify how an X.509 certificate is considered valid. This can be done by deriving a class from the X509CertificateValidator and overriding the Validate method.
This is the relevant MSDN document:
X509CertificateValidator Class
You seem to mention using this method in your question, but you don't post the code for the relevant class. I think you can try my code.
But at the same time, this also involves the question of how to judge how to judge the certificate of your network of more than 90 services. So I'm assuming here that you can judge by the issuer.
public class CustomCertificateValidator : X509CertificateValidator
{
public override void Validate(X509Certificate2 certificate)
{
if (certificate == null)
{
throw new ArgumentNullException("certificate");
}
if (certificate.Issuer != "CN=QiYOU")
{
throw new SecurityTokenValidationException("Not trusted.");
}
}
}
MyClient.ClientCredentials.ServiceCertificate.Authentication.CustomCertificateValidator = new CustomCertificateValidator();
You also can try :MyClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
The certificate is valid if it is in the trusted people store, or if the chain builds to a certification authority in the trusted root store.
This is the relevant MSDN document:
Upvotes: 0