运行ServiceHost时无法同时支持http和https url

时间:2018-06-21 10:55:09

标签: c# wcf

我正试图在ServiceHostHTTP上同时公开HTTPS

以下是运行服务的代码:

oServiceHost = new ServiceHost(typeof(API), new Uri(WebHookURL))
oServiceHost.Open();

正如您在这里看到的那样-我在运行时获取服务URL(WebHookURL)。 如前所述,URL协议可以是HTTPHTTPS

经过大量的阅读和测试,最终归结为这个web.config文件:

 <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>

尝试将WebHookURL(例如:http://localhost:8111)设置为http地址时-代码可以正常工作。

不幸的是,当将WebHookURL设置为https地址(例如: https :// localhost:8111)时,代码将不起作用,并且在以下情况下抛出此异常尝试创建ServiceHost实例:

Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https].

我想念什么?

更新1:

尝试了此配置,但出现配置错误: 尝试了这个,但是我遇到配置错误:

<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 个答案:

答案 0 :(得分:0)

问题在这里:

   <webHttpBinding>
        <binding name="webBinding">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </webHttpBinding>

webHttpBinding仅支持 HTTP 请求,不支持 HTTPS 请求。 webHttpBinding也不支持互操作性。

WsHttpBinding还支持互操作性。使用此绑定,默认情况下会加密SOAP消息。它支持HTTP和HTTPS。在编码方面,它支持Text以及MTOM编码方法。它支持WS- *标准,例如WS-Addressing,WS-Security和WS-ReliableMessaging。默认情况下,可靠会话是禁用的,因为这可能会导致性能降低。 http://www.codeproject.com/Articles/431291/WCF-Services-Choosing-the-appropriate-WCF-binding

因此,要使用https,请将webHttpBinding替换为WsHttpBinding

以下是与您的解决方案匹配的代码段:

1)为服务编写两个端点,一个端点为http,另一个端点为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)在serviceBehaviors中同时启用httpGetEnabled =“ True” httpsGetEnabled =“ true”。

<behaviors>

<serviceBehaviors>      
  <behavior name="MyServiceBehavior">
    <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
  </behavior>      
</serviceBehaviors>

<endpointBehaviors>
  <behavior name="WebBehavior">
    <webHttp/>
  </behavior>
</endpointBehaviors>

</behaviors>

3)为http和https编写两个绑定配置。对于http,请提供安全性模式=“ None”,对于https,请提供安全性模式=“ 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>

选中此link

答案 1 :(得分:0)

<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>

在上述配置中定义的端点中,绑定值指定为webHttpBinding。但是,为这些绑定提供的配置是为wsHttpBinding定义的。显然,绑定类型与其配置之间不匹配。下面的更改应解决此错误。

<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>

在以下代码段中,transport元素也是多余的,因为安全模式为None,因此可以删除。

<binding name="webBinding">
  <security mode="None">
    <transport clientCredentialType="None"/>
  </security>
</binding>

答案 2 :(得分:0)

这里是另一个想法:为什么不只允许HTTPS请求,而是将HTTP请求重新路由为https请求。如果您的Web服务器具有IIS,那么您可能会发现this有用

并可以通过like

完成http请求

我们通常在NLB节点(网络负载平衡)上应用证书,并在所有单个Web服务器上将http配置为https路由

答案 3 :(得分:0)

实际上很简单。您需要做的是为http绑定一个,为https绑定另一个,像这样:

<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>