如何将单个 WCF 服务配置为具有多个 HTTP 和 HTTPS 端点?
Posted
技术标签:
【中文标题】如何将单个 WCF 服务配置为具有多个 HTTP 和 HTTPS 端点?【英文标题】:How to configure a single WCF Service to have multiple HTTP and HTTPS endpoints? 【发布时间】:2011-04-18 23:22:25 【问题描述】:我想要做的是让一个 WCF 服务在作为 HTTP 方案的开发环境中工作,并且让 SAME 服务在作为 HTTPS 方案的生产环境中工作。如果我删除两个 Https 端点(后缀为“Https”),它可以在开发环境中工作;同样,如果我只删除两个 Http 端点,那么它可以在生产环境中工作。如果可能,我希望在 web.config 中包含所有四个端点。
我的端点定义如下:
<endpoint address="/Web"
behaviorConfiguration="AjaxBehavior"
binding="wsHttpBinding"
bindingConfiguration="web"
name="Web"
contract="Service" />
<endpoint address="/Custom"
binding="customBinding"
bindingConfiguration="custom"
name="Custom"
contract="Service" />
<endpoint
address="/WebHttps"
behaviorConfiguration="AjaxBehavior"
binding="wsHttpBinding"
bindingConfiguration="webHttps"
name="WebHttps"
contract="Service" />
<endpoint address="/CustomHttps"
binding="customBinding"
bindingConfiguration="customHttps"
name="CustomHttps"
contract="Service" />
已编辑:我正在编辑我的问题以添加我遇到的错误以及绑定部分(如下)。抱歉问题的新长度。
错误是: “找不到与绑定 WebHttpBinding 的端点的方案 http 匹配的基地址。注册的基地址方案是 [https]。”
此外,生产站点设置为“需要 SSL”。这是无法改变的。
绑定配置为:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="custom">
<textMessageEncoding>
<readerQuotas maxDepth="7000000" maxStringContentLength="7000000"
maxArrayLength="7000000" maxBytesPerRead="7000000"
maxNameTableCharCount="7000000" />
</textMessageEncoding>
<httpTransport maxBufferPoolSize="7000000" maxReceivedMessageSize="7000000"
maxBufferSize="7000000" />
</binding>
<binding name="customHttps">
<textMessageEncoding>
<readerQuotas maxDepth="7000000" maxStringContentLength="7000000"
maxArrayLength="7000000" maxBytesPerRead="7000000"
maxNameTableCharCount="7000000" />
</textMessageEncoding>
<httpsTransport maxBufferPoolSize="7000000" maxReceivedMessageSize="7000000"
maxBufferSize="7000000" />
</binding>
</customBinding>
<webHttpBinding>
<binding name="web" maxBufferPoolSize="70000000"
maxReceivedMessageSize="70000000">
<readerQuotas maxDepth="70000000" maxStringContentLength="70000000"
maxArrayLength="70000000" maxBytesPerRead="70000000"
maxNameTableCharCount="70000000" />
<security mode="None" />
</binding>
<binding name="webHttps" maxBufferPoolSize="70000000"
maxReceivedMessageSize="70000000">
<readerQuotas maxDepth="70000000" maxStringContentLength="70000000"
maxArrayLength="70000000" maxBytesPerRead="70000000"
maxNameTableCharCount="70000000" />
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
有什么想法吗?
【问题讨论】:
您是否尝试过并得到最终解决方案? 【参考方案1】:按照这些步骤-
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>
<webHttpBinding>
<binding name="webBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
<binding name="webBindingHTTPS">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
查看link
【讨论】:
Vinay,谢谢你的建议。我试过了,我在新编辑的问题中收到了错误。我发布了我的绑定配置以供审核。此外,生产站点设置为“需要 SSL”。这是无法改变的。 您的端点为端点指定一个相对地址,这意味着它们都将使用相同的基地址,必须指定 http 或 https。您可以将端点地址更改为绝对地址(而不是 '/web' 让它说 'http:/myurl.com/web' 应该可以解决您的错误。 @SteveEllinger 我在 IIS 中有这个 bindings ((type:hostname:port)
):http:none hostaname:49759, https:pre.company.es:443 和 http:pre.company.es:80,是怎么回事端点地址?根据我的 servicemodel 配置,我的 svc 收到 Could not find a base address ...
错误或 404 not found
恐怕你的解决方案在这里被接受为正确答案,你甚至犯了绑定的基本错误【参考方案2】:
如果您使用 Visual Studio 2010 和 Web 应用程序项目部署,则可以使用 Web.config 转换语法将服务端点的 bindingConfiguration 指向启用 https 的绑定配置。
对我来说,我发现我只需要替换 Web.config 文件中的两个元素。端点的 bindingConfiguration 属性和 serviceMetadata 的 httpsGetEnabled 应该设置为 true。
这是默认(调试)配置中的 Web.config:
<service name="Service"
behaviorConfiguration="DefaultBehavior">
<endpoint name="ServiceEndpoint"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding"
contract="IService" />
</service>
...
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
这是 Web.Release.config 转换文件
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="True" xdt:Transform="Replace" />
<serviceDebug includeExceptionDetailInFaults="False" xdt:Transform="SetAttributes(includeExceptionDetailInFaults)"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service>
<endpoint bindingConfiguration="SecureTransportBinding"
xdt:Transform="SetAttributes(bindingConfiguration)"/>
</service>
</services>
这是我的绑定的样子,但它们非常标准。注意上面使用的名称:
<basicHttpBinding>
<binding name="SecureTransportBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
<security mode="Transport"/>
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
</binding>
<binding name="BasicHttpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
<security mode="None"/>
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
</binding>
</basicHttpBinding>
以下是有关 Web.config 转换的更多链接:
http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx
【讨论】:
谢谢! bindingCongifuration 转换正是我想要的。【参考方案3】:你会得到错误的原因有很多:
Could not find a base address that matches scheme http for the endpoint
with binding WebHttpBinding. Registered base address schemes are [https].
大部分原因来自 Web.config 设置,但也可能来自 IIS。我也遇到了同样的问题,如果你用 http 和 https 绑定来保护 Endpoints,你必须为你在 IIS->Site->Bindings 中创建的网站创建 http 和 https 绑定,否则你会得到这个错误。
【讨论】:
【参考方案4】:这是您可以从配置中设置绑定的原因之一:能够在不同的环境中使用不同的设置。
对您来说最简单的解决方案是使用 makecert 为您的开发环境创建测试证书,并在开发和生产机器上使用 HTTPS。
另一种解决方案是创建安装包 (msi) 并让管理员在安装过程中更改 enpoint 设置。
编辑:
您在两台机器上都拥有所有 4 个端点的要求是可以实现的,但在这种情况下,您的服务也将在生产环境中通过 HTTP 公开,并且拥有该服务的 WSDL 的每个人都会知道这一点。
【讨论】:
无法使用自签名证书,因为我需要使用 VS 开发服务器。这是一个可行的解决方案,但这将是我最后的手段。现在,我正在考虑使用 ServiceHostFactory 并从配置部分动态构建所有绑定和端点。我对 WCF 感到沮丧 您很沮丧,因为您使用的是不支持大多数 WCF 功能的 VS 开发服务器。 WCF 不是您沮丧的根源。不好的工具是。 我同意。 Visual Studio 开发服务器应该支持 HTTPS。如果这样做,它将创造一个更好的测试/调试环境。我主要对 VSDS 感到沮丧。如果 VSDS 支持,我只需要配置 HTTPS 方案。 【参考方案5】:默认接收超时为 10 分钟,因此 WCF 客户端将在空闲时间超过该限制后断开连接。如果需要保持连接,我该怎么办?
解决方案 #1:
服务器提供一个虚拟操作让客户端定期调用它,让它不空闲。
解决方案 #2:
在客户端和服务器中启用reliableSession 并将receiveTimeout 和inactivityTimeout 设置为“infinite”。 配置 sn -p 可能如下:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding" receiveTimeout="infinite">
<reliableSession inactivityTimeout="infinite" enabled="true" />
</binding>
</wsHttpBinding>
</bindings>
<services>
...
</services>
...
</system.serviceModel>
【讨论】:
问题在于如何处理在您的开发和生产环境中使用安全和不安全端点 - 而不是如何更改超时值。以上是关于如何将单个 WCF 服务配置为具有多个 HTTP 和 HTTPS 端点?的主要内容,如果未能解决你的问题,请参考以下文章
WCF IIS 托管服务由单个服务实现的多个服务合同 - 如何通过配置在端点之间共享 uri