Ask Learn
Preview
Please sign in to use this experience.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Something as simple as ad-hoc selfhosting a WCF service can be fairly difficult if you need to use https. This is because of all the underlying pieces than need to be configured to properly host on a secure transport. In this fairly lengthy posting, I will go through a walkthrough of creating a simple selfhosted HelloWorld WCF service, entirely by hand, and modify it to listen over https. Along the way, I will run into several common errors and give the solutions to these.
Disclaimer: By no means is this intended for production. The purpose of this is to give an example of test code which self-hosts a WCF service using https.
using System;
using System.ServiceModel;
namespace HttpsSelfhost
{
class Program
{
static void Main(string[] args)
{
string address = "https://localhost/HelloWorldService";
BasicHttpBinding binding = new BasicHttpBinding();
ServiceHost host = new ServiceHost(typeof(HelloWorldService));
host.AddServiceEndpoint(typeof(IHelloWorld), binding, address);
host.Open();
Console.WriteLine("Host is {0}. Press enter to close.", host.State);
Console.ReadLine();
host.Close();
}
}
[ServiceContract]
public interface IHelloWorld
{
[OperationContract]
void HelloWorld();
}
public class HelloWorldService : IHelloWorld
{
public void HelloWorld()
{
Console.WriteLine("Hello World!");
}
}
}
using System;
using System.ServiceModel;
namespace HelloWorldClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press enter when the service is opened.");
Console.ReadLine();
string address = "https://localhost/HelloWorldService";
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<IHelloWorld> factory = new ChannelFactory<IHelloWorld>(binding, address);
IHelloWorld client = factory.CreateChannel();
Console.WriteLine("Invoking HelloWorld on the service.");
client.HelloWorld();
Console.WriteLine("Press enter to quit.");
Console.ReadLine();
}
}
[ServiceContract]
public interface IHelloWorld
{
[OperationContract]
void HelloWorld();
}
}
string address = "https://localhost:1234/HelloWorldService";
Then restart VS as an admin. When I hit F5, I can start the client once the service indicates it's open.
string address = "https://localhost:1234/HelloWorldService";
This yields the following exception:
Parameter name: context.ListenUriBaseAddress
binding.Security.Mode = BasicHttpSecurityMode.Transport;
netsh http add urlacl url=https://+:1234/ user=EVERYONE
makecert.exe -sk RootCA -sky signature -pe -n CN=<machineName> -r -sr LocalMachine -ss Root MyCA.cer
makecert.exe -sk server -sky exchange -pe -n CN=<machineName> -ir LocalMachine -is Root -ic MyCA.cer -sr LocalMachine -ss My <certificate path>
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace BindCertToPort
{
class Program
{
static void Main(string[] args)
{
int port = 1234;
string certPath = "MyAdHocTestCert.cer";
X509Certificate2 certificate = new X509Certificate2(certPath);
// netsh http add sslcert ipport=0.0.0.0:<port> certhash={<thumbprint>} appid={<some GUID>}
Process bindPortToCertificate = new Process();
bindPortToCertificate.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "netsh.exe");
bindPortToCertificate.StartInfo.Arguments = string.Format("http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}}", port, certificate.Thumbprint, Guid.NewGuid());
bindPortToCertificate.Start();
bindPortToCertificate.WaitForExit();
}
}
}
Note: If the certificate is still bound to the port, you still should be able to invoke the service over https.
X509Certificate2 cert = new X509Certificate2(certificatePath);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Remove(cert);
store.Close();
I want to reiterate that none of the above examples are intended for production; I'm only presenting them to provide one example of how to manually set up a self-hosted WCF service which uses https.
Anonymous
December 10, 2010
Instead of makecert, you could use SelfSignedCertificate class from NetFx:
www.maciejaniserowicz.com/.../WCF-Auth-starter-zalazek-aplikacji-klient-serwer-z-uwierzytelnianiem-usernamepassword.aspx
The comment from "26 lipca 2010 17:25"
Anonymous
November 15, 2011
Did not work until I defined a binding in IIS to use https over the (localhost) certificate created according to your example ... is this a must???
Anonymous
November 15, 2011
Another problem I've faced, only localhost worked for me, any other name did not work. any suggestions ( for sure from another computer it did not work at any cost!!
Anonymous
November 20, 2011
Ok, Great ... the secret is that any certificate will not be considered if it had "Issued to" field not matching the server name or domain name ... Excellent work :)
Anonymous
August 12, 2012
Better, use UWS - a free redistributable web server for ASP.NET that has full certificate management and can host WCF apps just fine.
ultidev.com/.../UWS-Cassini-Pro
Anonymous
May 06, 2013
s
Anonymous
May 06, 2013
Exception Occurs on ClientSide
"Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost:8086"
Inner Exception
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Anonymous
April 05, 2014
Awesome. It worked, but the code failed. becz the string certPath = "MyAdHocTestCert.cer"; this is something was throwing error, so I opened the certificate which was available under Persona->Certitficates->open the certificate look for thumbprint values and copy and paste with out spaces in it' . It got registered successfully. Thanks a ton. Good Post
Anonymous
October 28, 2014
Exception Occurs on ClientSide
"Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost:8086"
Inner Exception
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Anonymous
October 28, 2014
To check if the certificate is bound to the port. Use
netsh http show sslcert ipport=0.0.0.0:port
Mine was not bound when i ran the above.
Finally worked.
:)
Thank you
Anonymous
May 21, 2015
Client app is getting below exception:
"Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost:8086"
Inner Exception
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
How did you fix it? I've isntalled MyCA.cer on the client PC, is that right?
Anonymous
July 30, 2015
Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost:8002
Please sign in to use this experience.
Sign in