7

Ok so I am hosting a WCF service within a console application.

all bindings are created programatically, so no config settings.

I have a working service as long as I use HttpTransportBindingElement however as soon as I use HttpsTransportBindingElement then nothing works, the service does not display within the browser and the client application returns a 405 (Method Not Allowed) CommunicationException

I have tried setting a SecurityBindingElement to my CustomBinding but I am not sure which option I should be using.

SecurityBindingElement.CreateCertificateOverTransportBindingElement()

SecurityBindingElement.CreateAnonymousForCertificateBindingElement()

etc.

The code for the creation of the host is below

baseAddress = new Uri(string.Format("{0}://{1}", strConnectionType, ConfigurationManager.AppSettings["baseAddress"]));

            ServiceHost host = new ServiceHost(typeof(IMyService), baseAddress);

            host.AddServiceEndpoint(typeof(MyService), binding, String.Empty);

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpsGetEnabled = certificate != null;
            smb.HttpGetEnabled = certificate == null;

            host.Description.Behaviors.Add(smb);

            ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();

            if (sdb == null)
            {
                host.Description.Behaviors.Add(new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });
            }
            else
            {
                if (!sdb.IncludeExceptionDetailInFaults)
                {
                    sdb.IncludeExceptionDetailInFaults = true;
                }
            }


            if (certificate != null)
            {
                host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, certificate.Thumbprint);
            }
Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
Squirrel5853
  • 2,376
  • 1
  • 18
  • 34
  • 1
    What is `binding`? Also programmatic configuration of WCF services is goddamn hard, why not use the config file? – ta.speot.is Aug 05 '13 at 12:45
  • @ta.speot.is could you elaborate more on your question? – Squirrel5853 Aug 05 '13 at 12:47
  • @ta.speot.is because I am special :) as I have said the service runs fine over HTTP just an issue with HTTPS I am assuming it must be something simple I am missing and I think its to do with the security element not correctly configured. – Squirrel5853 Aug 05 '13 at 12:52
  • 1
    There has been similar question answered here http://stackoverflow.com/questions/3140526/wcf-https-vs-http – Jozef Benikovský Aug 05 '13 at 12:53
  • @JozefBenikovský yes although in that scenario it was using a `BasicHttpBinding` which takes care of alot of the binding elements – Squirrel5853 Aug 05 '13 at 13:01
  • Make sure the ServiceMetadataBehavior.HTTPSGetEnabled or HTTPGetEnabled matches the SSL setting you're using. Make sure, too, that when you turn on SSL that your endpoint URL starts with "https:" You'd be shocked how many people forget that. – Brian Aug 05 '13 at 14:30
  • @Brian yes I have made that mistake throughout my testing, however you do get different Comms Exceptions when that occurs :) within my code I, if the user has specified to start a server with https I then request for them to choose a certificate to use. I then use the certificate object to set the appropriate flags like so `smb.HttpsGetEnabled = certificate != null;` `smb.HttpGetEnabled = certificate == null;` – Squirrel5853 Aug 05 '13 at 15:20

1 Answers1

6

I followed this blog http://blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/10/selfhosting-a-wcf-service-over-https.aspx which highlighted that in order for HTTPS to work you need to bind the port to the certificate you are using.

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();

once this was done it all worked.

contact me if any requires my example code of setting up and configuring a self-hosted WCF server with bindings programatically set. :)

Squirrel5853
  • 2,376
  • 1
  • 18
  • 34