在 exe 托管的 WCF Web 服务中启用 HSTS 简单的方法:Strict-Transport-Security:更好的方法:var context = WebOperationContext.Current; if( context is null ) throw new InvalidOperationContext( "WebOperationContext not found. Are you running in the right thread?"

问题描述

我有一个 WCF 服务,它使用 ServiceHost 类托管在 exe 中。我称它为“网络服务”,因为它通过 https 进行侦听,因此我可以从网络浏览器 ping 它。 (抱歉,如果我的所有术语都不准确。)

我想为此网络服务启用 HSTS。 我发现我可以通过将其放入 Web.config 来启用它:

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Strict-Transport-Security" value="max-age=31536000"/>
  </customHeaders>
</httpProtocol>

<rewrite>
  <rules>
    <rule name="HTTP to HTTPS redirect" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
    </rule>
  </rules>

  <outboundRules>
    <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
      <match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
      <conditions>
        <add input="{HTTPS}" pattern="on" ignoreCase="true" />
      </conditions>
      <action type="Rewrite" value="max-age=31536000" />
    </rule>
  </outboundRules>
</rewrite>

但我没有 Web.config,因为该服务未托管在 IIS 中。 我试图将它添加到 system.ServiceModel 部分,但没有效果。 我不确定是否可以在没有 IIS 支持的情况下处理 system.webServer 部分。 我也不确定 HSTS 在没有 IIS(或 Apache)的情况下是否是一个有效的概念。

我目前阅读的所有文章都只描述了 IIS 场景。

https://www.hanselman.com/blog/how-to-enable-http-strict-transport-security-hsts-in-iis7

https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/hsts

https://www.forwardpmx.com/insights/blog/the-ultimate-guide-to-hsts-protocol/

所以我的问题是:如何在这种情况下启用 HSTS?

编辑: 我的服务模型配置(编辑以掩盖我们的产品名称

<system.serviceModel>
<services>
  <service behaviorConfiguration="AServiceBehavior" name="something.RemoteAccess.WebAccess.A.Core.A">
    <endpoint address="" behaviorConfiguration="AEndpointBehavIoUr" binding="basicHttpBinding" bindingConfiguration="secureBasicHttpBinding" name="A" bindingNamespace="uri:something.RemoteAccess.WebAccess.A" contract="something.RemoteAccess.WebAccess.A.IService"/>
    <host>
      <baseAddresses>
        <add baseAddress="https://*:4510/somethingWebAccess/A"/>
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="secureBasicHttpBinding">
      <security mode="Transport">
        <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <endpointBehaviors>
    <behavior name="AEndpointBehavIoUr">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="AServiceBehavior">
      <serviceMetadata httpsGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

解决方法

我曾尝试将其添加到 <system.ServiceModel> 部分,但没有效果。我不确定是否可以在没有 IIS 支持的情况下处理 <system.webServer> 部分。我也不确定 HSTS 在没有 IIS(或 Apache)的情况下是否是一个有效的概念。

正确。 <system.webServer> 元素特定于 IIS 7 及更高版本(包括 IIS Express)。

app.configweb.config 文件的架构是明确定义的 - 它不是魔法:四处移动元素不会导致库中的功能突然起作用在另一个不相关的图书馆。

(尽管 <system.web> (ASP.NET) 和 <system.webServer> (IIS) 之间存在一些共性,但这只是巧合——或者因为托管管道系统,我明白为什么这会引起混乱0。


您的 <rewrite> 部分根本无法工作,因为这取决于 IIS 是否安装了 IIS URL 重写模块(它是一个可选组件,默认情况下未安装)。 >


如果没有 IIS(或 Apache),我也不确定 HSTS 是否是一个有效的概念。

HSTS 适用于任何 HTTP 服务:它只是意味着网络服务器(或网络应用程序,它不必是主机/服务器问题)正在发送 {{1 }} 标题。

您仍然可以在 WCF 中执行此操作。

简单的方法:Strict-Transport-Security

WCF adding additional HTTP header to HTTP response for transporting SOAP message

WebOperationContext

缺点:您需要将此代码(或调用实现此代码的函数)添加到您的所有 WCF 操作/端点/等。这样做的好处是,您无需担心理解 WCF 的“行为”系统。

更好的方法:var context = WebOperationContext.Current; if( context is null ) throw new InvalidOperationContext( "WebOperationContext not found. Are you running in the right thread?" ); context.OutgoingResponse.Headers.Add( "Strict-Transport-Security","max-age=31536000" );

https://weblogs.asp.net/paolopia/writing-a-wcf-message-inspector

在这里总结有点复杂,抱歉。

最佳方法:自定义行为

从我上次编写任何 WCF 代码到现在已经字面上整整十年了,我已经忘记了如何进行自定义行为。对不起,我不能再有用了:/