如何在一个web.config中组合http和https的WCF服务配置?

时间:2010-12-03 15:19:27

标签: web-config wcf wcf-binding

我花了很多时间搞清楚如何配置我的WCF服务,以便它们适用于生产环境中的https。

基本上,我需要这样做:

<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
  <service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
    <endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="HttpsBinding">
      <security mode="Transport">
        <transport clientCredentialType="None"></transport>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

bindingNamespace属性添加到端点是使其工作的最终因素。

但是这个配置在我在普通http下工作的本地开发环境中不起作用。所以我的配置是:

<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
  <service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
    <endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
  </service>
</services>

这里的不同之处在于我将httpsGetEnabled属性设置为false,并删除了bindingConfiguration和bindingNamespace。

问题是:如何创建一个处理BOTH的配置块?

我真的很讨厌每次发布时都要对配置进行大量的特殊修改。是的,我知道我可以有一个自动更改值的后期构建任务,但是如果可能的话我想合并配置。

我试过这样的事情:

<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
  <service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
    <endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
    <endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="HttpsBinding">
      <security mode="Transport">
        <transport clientCredentialType="None"></transport>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

我认为放置两个端点会在激活服务时为其提供两个选项。但是,这不起作用。我收到这个错误:

无法找到与绑定BasicHttpBinding的端点的方案https匹配的基址。注册的基地址方案是[http]。

从环顾SO和互联网的其余部分来看,似乎其他人在杀死这条龙时遇到了问题。

4 个答案:

答案 0 :(得分:16)

好吧,你的组合配置的一个问题是你的两个端点在同一个地址 - 这是行不通的。

如果您在IIS中托管,那么您的服务器,虚拟目录和所需的* .svc文件将决定您的基本地址 - 它将类似于:

http://yourservername/VirtualDirectory/YourService.svc

如果您想拥有两个端点,则至少有一个端点需要定义相对地址:

<services>
    <service name="MyNamespace.MyService" 
             behaviorConfiguration="MyServiceBehavior">
       <endpoint 
           address="basic" 
           binding="basicHttpBinding" 
           contract="MyNamespace.IMyService"/>
       <endpoint 
           address="secure" 
           binding="basicHttpBinding" bindingConfiguration="HttpsBinding"  
           contract="MyNamespace.IMyService"/>
    </service>
</services>

在这种情况下,您将拥有HTTP端点:

http://yourservername/VirtualDirectory/YourService.svc/basic

以及您的安全HTTPS端点:

https://yourservername/VirtualDirectory/YourService.svc/secure

此外:您的安全端点使用HttpsBinding配置 - 但您缺少这样的绑定配置 - 您所拥有的只是:

<bindings>
  <basicHttpBinding>
    <binding name="HttpBinding">
      <security mode="None">
        <transport clientCredentialType="None"></transport>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

您需要添加HttpsBinding配置!!

<bindings>
  <basicHttpBinding>
    <binding name="HttpBinding">
      <security mode="None">
        <transport clientCredentialType="None"></transport>
      </security>
    </binding>
    <binding name="HttpsBinding">
      <security mode="Transport">
          <transport clientCredentialType="Windows" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

答案 1 :(得分:2)

问题不在于配置文件,而在于IIS设置。 你需要启用HTTP和amp; IIS中的HTTPS。 在IIS 7.5中,转到您的站点并单击“编辑站点操作”下的“绑定”。确保http和&amp; https已被添加。 然后,您需要在<basicHttpBinding>下为HTTP创建绑定,并将安全模式设置为none。 将新创建的绑定配置添加到http端点。 你已准备好出发。如果您还需要进一步的问题,请告诉我。

答案 2 :(得分:0)

配置转换是在本地域中运行以及在生产环境和其他环境中运行而不依赖于内存进行任何更改的解决方案。他们根据所选的配置文件转换已编译的web.config。在本地,我以Debug模式运行,在测试环境中,我publishTestRelease配置文件,而生产环境我有另一个配置文件:

Web.Config Transforms in Visual Studio

如果无法展开web.config,则可以右键单击并添加配置转换。为了获得除调试和发布以外的更多功能,您可以通过管理器添加更多配置:

Configuration Manager in Visual Studio

以下是示例转换:

Web.Debug.config

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <!--...-->
  <system.serviceModel>
    <protocolMapping>
      <add binding="basicHttpBinding" scheme="http" xdt:Transform="SetAttributes" />
    </protocolMapping>
    <bindings>
      <basicHttpBinding>
        <binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
          <security xdt:Transform="Remove">
            <transport xdt:Transform="Remove"/>
          </security>
        </binding>
        <binding xdt:Locator="Match(name)" name="fileTransferBinding">
          <security xdt:Transform="Remove">
            <transport xdt:Transform="Remove"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Web.Release.config

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <!--...-->
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" xdt:Transform="Replace"/>
          <serviceDebug includeExceptionDetailInFaults="false" xdt:Transform="Replace"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" xdt:Transform="Replace"/>
    </protocolMapping>
    <bindings>
      <basicHttpBinding>
        <binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
          <security mode="Transport" xdt:Transform="Insert">
            <transport clientCredentialType="None" proxyCredentialType="None" />
          </security>
        </binding>
        <binding xdt:Locator="Match(name)" name="fileTransferBinding">
          <security mode="Transport" xdt:Transform="Insert">
            <transport clientCredentialType="None" proxyCredentialType="None" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
  <system.webServer>
    <directoryBrowse enabled="false"  xdt:Transform="Replace"/>
  </system.webServer>
</configuration>

答案 3 :(得分:0)

最近,我不得不在Microsoft Azure应用程序服务(IIS)中的HTTP和HTTPS上都提供WCF 3.5 REST(webHttpBinding)服务。这是一个有趣的冒险经历。这是我的发现和我的web.config的{​​{1}}:

说明:这些说明适用于在最小的ASP.NET 4.7应用程序(带有{{1)中使用<system.serviceModel>*.svc)个文件运行的WCF REST Web服务}})在Windows Server 2016的IIS 10中。这些注意事项不适用于不适用于自托管WCF服务,非REST WCF服务(即SOAP)或早于.NET Framework 4.7的平台。这也不适用于.NET Core。

  • 升级到.NET Framework 4.7.2或更高版本(这只是常识)
  • 最重要的部分是使用@ServiceHost元素是必不可少的,请确保已设置Global.asax
  • 完全不需要在您的multipleSiteBindingsEnabled="true"文件中使用<baseAddressPrefixFilters>元素。
    • 显然,此元素用于WSDL元数据-RESTful服务不支持WSDL。
    • 我指出这一点是因为至少有一些文章和StackOverflow帖子在Google上排名靠前,而人们认为这是必需的。这些人是不正确的。
  • 请勿在您的<serviceMetadata>属性中使用绝对URI,只需将属性留空即可。
  • 如果托管应用程序(即IIS)中未启用HTTPS,<endpoint address=""文件告诉WCF接受HTTPS连接,则WCF将检测是否可以同时使用HTTP和HTTPS到达,并且将引发错误。父网站。
    • 这对我来说是意外的,因为我使用过的所有其他Web应用程序平台都不会抱怨它们是否配置了HTTPS,而未使用父Web服务器。
      • 特别考虑到在这种情况下,WCF在.NET请求管道中/内部运行,并且ASP.NET肯定不在乎IIS的网站绑定(因为ASP.NET被设计为与父网站绑定无关) / li>
      • 注意:“网站绑定”是指IIS网站绑定,不是“ WCF绑定”,这是一个单独的概念。
  • 要使其在Visual Studio和IIS Express中本地运行,请确保父Web应用程序项目在“属性”窗口中具有“ SSL Enabled = True”(与“项目属性”窗口不同)(是,我也尖叫):
    • enter image description here
  • 在.NET 4.6.1中,Microsoft简化了WCF的配置,允许省略PATH_INFO元素并在幕后自动生成,但是使用双重功能的RESTful服务并没有获得一致的结果HTTP + HTTPS绑定,因此我仍然手动指定web.config

TL; DR:

这是我的<services>文件中的<services>元素:

<system.serviceModel>