运行 ServiceHost 时不能同时支持 http 和 https url
Posted
技术标签:
【中文标题】运行 ServiceHost 时不能同时支持 http 和 https url【英文标题】:Cannot support both http and https url when running a ServiceHost 【发布时间】:2018-11-30 16:24:02 【问题描述】:我正在尝试在HTTP
和HTTPS
上启用ServiceHost
。
这是运行服务的代码:
oServiceHost = new ServiceHost(typeof(API), new Uri(WebHookURL))
oServiceHost.Open();
正如您在此处看到的 - 我在运行时获取服务 URL (WebHookURL
)。
如前所述,URL 协议可以是HTTP
或HTTPS
。
经过大量阅读和测试,最终得到了这个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,然后转发请求 【参考方案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 绑定。或者,如果您不需要它们,您可以移除肥皂绑定。以上是关于运行 ServiceHost 时不能同时支持 http 和 https url的主要内容,如果未能解决你的问题,请参考以下文章
mexHttpBinding - 将 ServiceMetadataBehavior 添加到配置文件或直接添加到 ServiceHost 以启用对此协定的支持
TestNG 数据驱动注解,可配合Grid支持多node机器,多浏览器同时运行脚本