Last week, I was asked to help troubleshoot a problem with one of our WCF services. It was an external service that was to be consumed by a vendor. It was necessary to use SSL and on our network we use an F5 Big-IP device for load balancing. The external DNS points to the F5 device which forwards the call on to the appropriate service on the internal server hosting the WCF service. Things get a little tricky with the F5 and SSL. Requests come in to the F5 over HTTPS. The HTTPS request is terminated at the F5 and the decrypted request is forwarded to the internal machine over plain HTTP. How does one configure the WCF service and client when the client needs to send the request over HTTPS, but the service is going to receive it as HTTP?
Here’s the solution I came up with: First, both client and server need to use a basicHttpBinding. On the server side, I set the security mode to “TransportCredentialOnly” for the binding, then set the endpoint address as “http://domain.com/MyService.svc”. On the client side, the security mode for the binding is set to “Transport” and then endpoint address is set to “https://domain.com/MyService.svc”. The key difference being the registration of the client endpoint as https, while the service endpoint listens on http.
The test harness we built was then able to successfully consume the WCF service. The next problem was that the vendor still needed access to the schemas. In order to generate the schema automatically, the httpGetEnabled attribute on the service behavior needs to be set to true. Problem is, if it is set, the auto-generated path to the schema is over http, which would get blocked at the F5 device because it is only expecting secure traffic. If I took the generated path, but substituted https for http I could resolve the WSDL. So, what I ended up doing was as a temporary solution was to download the auto-generated schemas. I updated the references within the WSDL and XSD files so that they all used https to resolve addresses related to our service, then published these files to a “Schema” directory on the web server where the service was running. I then turned off the httpGetEnabled attribute on the service behavior, enabled the httpsGetEnabled attribute and set the httpsGetUrl to the URI for the WSDL I had just uploaded to the “Schema” folder. I fired up Visual Studio and added the Service Reference without issue.
I would’ve liked to have been able to have been allocated to coming up with the permanent solution for the WSDL, but I was reassigned as the immediate need was resolved. I suggested looking into deriving a class from the WsdlExporter that could enforce https for any schema URI related to the service. I don’t know if it’ll work, but it seemed as good a place as any to start.