I'm trying to enable exposing a ServiceHost
on both HTTP
& HTTPS
.
Here is the code that runs the service:
oServiceHost = new ServiceHost(typeof(API), new Uri(WebHookURL)) oServiceHost.Open();
As you can see here - I'm getting the service URL (WebHookURL
) during runtime. As mentioned, URL protocol can be either HTTP
or HTTPS
.
After lots of reading and testing, it came down to this web.config
file:
<system.serviceModel> <client> <endpoint binding="customBinding" bindingConfiguration="encryptingBinding" contract="ModuleComm.Commons.ServiceContracts.ModuleService" name="clientConf" /> </client> <services> <service name="myServiceWebServer.AsynchronousSocketListener"> <endpoint binding="customBinding" bindingConfiguration="encryptingBinding" contract="ModuleComm.Commons.ServiceContracts.ModuleService" /> </service> <service behaviorConfiguration="API.Service1Behavior" name="myServiceWebServer.API"> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="myServiceWebServer.IAPI" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="API.Service1Behavior"> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" /> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="web"> <webHttp /> </behavior> </endpointBehaviors> </behaviors> <bindings> <customBinding> <binding name="encryptingBinding"> <!-- <messageEncryping /> --> <textMessageEncoding> <readerQuotas maxStringContentLength="2147483647" /> </textMessageEncoding> <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"> <connectionPoolSettings leaseTimeout="23:59:00" maxOutboundConnectionsPerEndpoint="10000" /> </tcpTransport> </binding> </customBinding> <webHttpBinding> <binding name="webBinding"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </webHttpBinding> </bindings> <protocolMapping> <add binding="webHttpBinding" bindingConfiguration="webBinding" scheme="https" /> </protocolMapping> </system.serviceModel>
When trying to set WebHookURL
(e.g: http://localhost:8111) to an http
address - code works fine.
Unfortunately, when setting WebHookURL
to an https
address (e.g: https://localhost:8111) - code won't work and this exception is thrown when trying to create the ServiceHost
instance:
Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https].
What am I missing ?
UPDATE 1:
Tried this configurations but i'm getting configuration error: Tried this but i'm getting configuration error:
<system.serviceModel> <services> <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API"> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" /> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="API.Service1Behavior"> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" /> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="web"> <webHttp /> </behavior> </endpointBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="webBinding"> <security mode="None"> <transport clientCredentialType="None"/> </security> </binding> <binding name="wsBindingHTTPS"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </wsHttpBinding> </bindings> </system.serviceModel>
4 Answers
Answers 1
the problem is here:
<webHttpBinding> <binding name="webBinding"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </webHttpBinding>
The webHttpBinding
supports only HTTP requests and not HTTPS requests. webHttpBinding does not support interoperability as well.
WsHttpBinding
also supports interoperability. With this binding, the SOAP message is, by default, encrypted. It supports HTTP and HTTPS. In terms of encoding, it provides support for Text as well as MTOM encoding methods. It supports WS-* standards like WS-Addressing, WS-Security and WS-ReliableMessaging. By default, reliable sessions are disabled because it can cause a bit of performance overhead. http://www.codeproject.com/Articles/431291/WCF-Services-Choosing-the-appropriate-WCF-binding
So in order to use https, replace webHttpBinding
with WsHttpBinding
.
Here is a snippet that will match your solution:
1) Write two endpoints for the service, one is for http and another for https.
<services> <service behaviorConfiguration="MyServiceBehavior" name="JK.MyService"> <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="JK.IMyService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBindingHTTPS" contract="JK.IMyService"> <identity> <dns value="localhost" /> </identity> </endpoint> </service> </services>
2) Enable both httpGetEnabled="True" httpsGetEnabled="true" in serviceBehaviors.
<behaviors> <serviceBehaviors> <behavior name="MyServiceBehavior"> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="WebBehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors>
3) Write two bindings configurations for http and https. For http give security mode="None" and for https give mode="Transport".
<bindings> <wsHttpBinding> <binding name="webBinding"> <security mode="None"> <transport clientCredentialType="None" /> </security> </binding> <binding name="webBindingHTTPS"> <security mode="Transport"> <transport clientCredentialType="None" /> </security> </binding> </wsHttpBinding> </bindings>
Check this link
Answers 2
<services> <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API"> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" /> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services>
In the endpoints defined in the configuration above, the value for binding is specified as webHttpBinding
. However, the configuration provided for those bindings are defined for wsHttpBinding
. Clearly there is a mismatch between the type of binding and its configuration. The below change should fix this error.
<services> <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API"> <endpoint address="" behaviorConfiguration="web" binding="wsHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" /> <endpoint address="" behaviorConfiguration="web" binding="wsHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services>
Also in the below snippet, the transport
element is redundant since the security mode is None
and hence can be removed.
<binding name="webBinding"> <security mode="None"> <transport clientCredentialType="None"/> </security> </binding>
Answers 3
Here is another idea: Why not allow HTTPS requests ONLY and re-route http request into https request. If your web server has IIS then you may find this useful
and bar http request can be done like
we generally apply certificate on NLB Node(Network Load Balanced) and configure http to https route on all individual web servers
Answers 4
actually its simple. all you need is one binding for http and another one for https like this:
<bindings> <basicHttpBinding> <binding name="SoapBinding" /> </basicHttpBinding> <mexHttpBinding> <binding name="MexBinding" /> </mexHttpBinding> <mexHttpsBinding> <binding name="SecureMexBinding" /> </mexHttpsBinding> <basicHttpsBinding> <binding name="SecureSoapBinding" /> </basicHttpsBinding> <webHttpBinding> <binding name="RestBinding" /> <binding name="SecureRestBinding" > <security mode="Transport" /> </binding> </webHttpBinding> </bindings> <services> <service behaviorConfiguration="ServiceBehavior" name="myServiceWebServer.API"> <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="SoapBinding" name="Soap" contract="myServiceWebServer.IAPI" /> <endpoint address="soap" binding="basicHttpsBinding" bindingConfiguration="SecureSoapBinding" name="SecureSoap" contract="myServiceWebServer.IAPI" /> <endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="RestBinding" name="Rest" contract="myServiceWebServer.IAPI" /> <endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="SecureRestBinding" name="SecureRest" contract="myServiceWebServer.IAPI" /> <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="MexBinding" name="Mex" contract="IMetadataExchange" /> <endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="SecureMexBinding" name="SecureMex" contract="IMetadataExchange" /> </service> </services>
0 comments:
Post a Comment