C# – How to set up a secure WCF service behind a firewall

ciiswcfweb services

I have a WCF service that is behind an enterprise-class firewall, which is doing both hostname and port translation, e.g.:

https://ws.address.com/Service.svc –> https://serv.internal.com:44000/Service.svc

The service is secured with SSL-128 and requires a client certificate.

Because the internal server name is not accessible from outside the firewall, we had to implement a ServiceHostFactory to translate the WSDL and XSD import references that WCF generates:

public class MyCustomFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(
            Type serviceType, Uri[] baseAddresses)
        {
            MyCustomHost customServiceHost = 
                new MyCustomHost(serviceType, baseAddresses);

            return customServiceHost;
        }

        class MyCustomHost : ServiceHost
        {
            public MyCustomHost(Type serviceType, 
                params Uri[] baseAddresses)
                : base(serviceType, 
                    GetBaseAddresses(serviceType, baseAddresses))
            {                
            }

            protected override void ApplyConfiguration()
            {
                base.ApplyConfiguration();
            }

            private static Uri[] GetBaseAddresses(
                Type serviceType, params Uri[] baseAddresses)
            {
                UriBuilder newBaseAddress = new UriBuilder();
                newBaseAddress.Path = "/" + serviceType.ToString() + 
                    ".svc";

                // from config
                newBaseAddress.Host = 
                    MyCustomSettings.ServiceBaseAddress; 

                if (baseAddresses.Length > 0)
                {
                    newBaseAddress.Scheme = baseAddresses[0].Scheme;
                }

                return new Uri[] { newBaseAddress.Uri };
            }
        }
    }

Here's the problem with this: unless the service is hosted on the internal machine on the default SSL port of 443, we get the error:

No protocol binding matches the given address 'https://ws.address.com/Service.svc'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

It appears, from tinkering, that if we change the internal server to host the service on 443, or configure the firewall to forward from 44000 to 44000, everything works. Those aren't options in our production environment, though.

Edit: Forgot to mention, we tried to use an IWsdlExportExtension to flatten the WSDL, but that caused severe problems with the proxy code generation in svcutil or VS2008, so we scrapped the idea.

Does anyone know any way around this? I'm pulling my hair out!

Thanks in advance!

Best Answer

You may need to explicitly create your own Binding (i.e., ServiceModel.WSHttpBinding) and add a Service Endpoint (.AddServiceEndpoint(..) ) with that binding.

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehost.addserviceendpoint(VS.85).aspx

Related Topic