【问题标题】:Cannot support both http and https url when running a ServiceHost运行 ServiceHost 时不能同时支持 http 和 https url
【发布时间】:2018-11-30 16:24:02
【问题描述】:

我正在尝试在HTTPHTTPS 上启用ServiceHost

这是运行服务的代码:

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>

【问题讨论】:

  • 更好的方法是在前面放置一个网络服务器并终止服务器上的 SSL,然后转发请求

标签: c# wcf


【解决方案1】:

问题出在这里:

   <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

这是一个与您的解决方案相匹配的 sn-p:

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

【讨论】:

  • 在我将其更改为 wsHttpBinding 后,我在尝试使用 https 时收到此错误:找不到与绑定 WebHttpBinding 的端点的方案 http 匹配的基地址。注册的基地址方案是 [https]。
  • 添加了一个sn-p。
  • 请看一下“UPDATE 1”..还是不行。
【解决方案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>

在上面配置中定义的端点中,绑定的值被指定为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>

同样在下面的 sn-p 中,transport 元素是多余的,因为安全模式是 None,因此可以删除。

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

【讨论】:

  • 尝试更改为 binding="wsHttpsBinding" 仍然无法正常工作。请注意,我在“UPDATE1”配置中有两种绑定(其中一种是 webHttpBinding)。
【解决方案3】:

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

并且可以做bar http请求like

我们通常在 NLB 节点(网络负载平衡)上申请证书,并在所有单独的 Web 服务器上配置 http 到 https 路由

【讨论】:

    【解决方案4】:

    其实很简单。您只需要一个绑定 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>
    

    【讨论】:

    • 不幸的是 - 在尝试了您建议的配置后,我收到此错误:“找不到与绑定 WebHttpBinding 的端点的方案 https 匹配的基地址。注册的基地址方案是 [http]。”
    • 很简单。我猜你在 iis 上托管了你的应用程序。确保在您的网站上同时添加 HTTP 和 HTTPS 绑定。或者,如果您不需要它们,您可以移除肥皂绑定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2021-11-07
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多