0

I am trying to understand certificate based authentication using the msdn sample https://msdn.microsoft.com/en-us/library/ms731074(v=vs.90).aspx

This is the server code:

WSHttpBinding binding = new WSHttpBinding(); 
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

// Create the URI for the endpoint. 
Uri httpUri = new Uri("https://localhost/Calculator");

// Create the service and add an endpoint. 
ServiceHost myServiceHost = new ServiceHost(typeof(ServiceModel.Calculator), httpUri); 
myServiceHost.AddServiceEndpoint(typeof(ServiceModel.ICalculator), binding, "");

// Open the service. 
myServiceHost.Open();

Console.WriteLine("Listening..."); 
Console.ReadLine();

// Close the service. 
myServiceHost.Close();

This is the client code I wrote:

ChannelFactory<ICalculator> factory = null;

WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

EndpointAddress address = new EndpointAddress("https://localhost/Calculator");

factory = new ChannelFactory<ICalculator>(binding, address);

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

factory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "sroger");

ICalculator channel = factory.CreateChannel();

int y = channel.add(9, 8);

I am getting the following exception:

An unhandled exception of type 'System.ServiceModel.CommunicationException' occurred in mscorlib.dll

Additional information: An error occurred while making the HTTP request to https://localhost/Calculator. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.

I am running both client and server from the same machine. And "sroger" is the certificate in my current user\ personal\certificates which corresponds to my machine name.. Not sure what to do from here..Any thoughts? In the server code what certificate server uses?

Thanks

Gulumal.

Gulumal
  • 59
  • 2
  • 8

1 Answers1

1

https://msdn.microsoft.com/en-us/library/ms731074(v=vs.90).aspx example you used is incomplete. Consuming https wcf service requires a valid server certificate to work, in your case both client and server certificates are required. This is because both client and server need to trust each other in a HTTPS connection.

To get started, read https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/message-security-with-mutual-certificates which is a more complete example that includes specifying certificate to authenticate the service.

For a hosted WCF library via https to work you need to do the following in order:

  1. Configure the port with an X.509 certificate (which has been answered in webHttpBinding with certificate)
  2. From your server, create certificate request for common name of your server fully qualified domain name, or at-least including a DNS subjectAltName of your server fully qualified domain name. (there are different ways to do this, you may already know this though)
  3. Issue certificate and install certificate on your server
  4. Grab application id from assembly file of your App that hosts WCF library (i.e [assembly: Guid("5870aeed-caca-4734-8b09-5c0615402bcf")]) Grab the certificate thumbprint by viewing certificate properties.
  5. As administrator, open CMD and run this command to bind X.509 certificate to the port used by your app on server

    netsh http add sslcert ipport=0.0.0.0:443 certhash= appid={} certstorename=MY

    netsh http add iplisten ipaddress=0.0.0.0:443

Add this to your server code:

myServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySerialNumber, "<certificate thumbprint>");

In your client code, reference your server address by fully qualified domain name that certificate that is specified as certificate Common Name or subject Alt Name

Iggy Zofrin
  • 515
  • 3
  • 10