Question

I am developing a WCF DataService that's self-hosted inside a Windows Console Application. I want to activate my service over Https (i.e. SSL) instead of Http. How can I do that?

Thanks

Was it helpful?

Solution

First Creating a CA Certificate on Windows (use Visual Studio Command Prompt):

makecert -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine

Now put the certificate in the "Trusted Root Certification Authority" in Windows Key Store. That can be done through MMC. To do that: Run... -> Type "mmc" -> enter -> choose the "Certificates" console -> Find your created certificate in the Personal store and move it to the Trusted Certificate Authority store.

Now we create an exchange certificate signed by the CA certificate:

makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

NOTE: The EKU OID is for Server Authentication
NOTE: the CN (Common Name) should be identical to the name by which the service will be called.

Now we add an Https endpoint to the data service. That can either be
1- Through the web.config file of the service, in which we'll have to enter a service endpoint:

<endpoint address="https://localhost:8888/" binding="basicHttpsBinding" contract="System.Data.Services.IRequestHandler"></endpoint>

2- Or with adding an endpoint programmatically using the "AddServiceEndpoint" of the DataServiceHost object:

host.AddServiceEndpoint(
                new ServiceEndpoint(ContractDescription.GetContract(typeof(TestODataService.DemoDataService)))
                {
                    Address = new EndpointAddress("https://localhost:8888/"),
                    Binding = new WebHttpBinding(WebHttpSecurityMode.Transport),
                    Contract = ContractDescription.GetContract(typeof(IRequestHandler)),
                }
                );

NOTE: The binding in the second method is necessarily WebHttpBinding with Transport security. While in the web.config method, it can be either basicHttpsBinding, or a webBinding with bindingConfiguration that enable transport security.

Now we bind the exchange certificate with the port of the service. In order for the WCF web server to respond to clients with the exchange certificate, we need to bind the certificate to the address of the service, using the netsh command: netsh http add sslcert ipport=0.0.0.0:8000 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}

NOTE: the certhash is the thumbprint of the exchange certificate, and the appid is the GUID of the hosting application found in the AssemblyInfo.cs of the project. The ip 0.0.0.0 binds to all ip address, and the port is the port of the service. This command is required to be used only once for each address.

NOTE: Some mobile devices may not be able to verify the identity of the service when called using the ip address of the service, even if the exchange certificate have the CN set to the ip address of the service. In this case the CN of the certificate should be a domain name.

NOTE: in order for the mobile device to trust the exchange certificate of the service, the CA certificate should be installed on the mobile in the Trusted CA Certificate store.

NOTE: Some browsers (e.g. Chrome) will object that the certificate is issued for localhost which is a name only used in your local network. This will not occur if you set the CN to a domain name.

Reference: http://www.codeproject.com/Articles/24027/SSL-with-Self-hosted-WCF-Service

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top