【问题标题】:How to force HTTPS using a web.config file如何使用 web.config 文件强制 HTTPS
【发布时间】:2012-03-22 13:14:28
【问题描述】:

我搜索了 Google 和 StackOverflow 试图找到解决方案,但它们似乎都与 ASP.NET 等有关。

我通常在我的服务器上运行 Linux,但对于这个客户端,我使用的是带有 IIS 7.5(和 Plesk 10)的 Windows。这就是我对 IIS 和 web.config 文件有点不熟悉的原因。在.htaccess 文件中,您可以使用重写条件来检测协议是否为 HTTPS 并进行相应的重定向。有没有一种简单的方法可以使用 web.config 文件,甚至使用我安装的“URL Rewrite”模块来实现?

没有使用 ASP.NET 的经验,所以如果解决方案中涉及到,那么请包括如何实施的明确步骤。

我使用 web.config 而 not PHP 这样做的原因是我想对站点内的所有资产强制使用 HTTPS。

【问题讨论】:

标签: c# asp.net iis https web-config


【解决方案1】:

您需要 URL Rewrite 模块,最好是 v2(我没有安装 v1,所以不能保证它可以在那里工作,但应该可以)。

这是一个这样的 web.config 示例——它将强制所有资源使用 HTTPS(使用 301 永久重定向):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

附言 此特定解决方案与 ASP.NET/PHP 或任何其他技术无关,因为它仅使用 URL 重写模块完成 - 它在初始/较低级别之一进行处理 - 在请求到达您的代码的位置之前执行。

【讨论】:

  • @BenCarey 你还应该看看Strict-Transport-Security 标头:en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
  • 我建议更改重定向,这样它就不会附加查询字符串,因为它已经是 {REQUEST_URI} 的一部分(否则参数会被添加两次)。 &lt;action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" /&gt;
  • 这行得通,但不幸的是也在本地主机上。为避免这种情况,您可以将其添加到
  • 使用 AWS Elastic beanstalk,这个方法给了我一个 302 Too many redirects,直到我修改:&lt;match url=".*"/&gt;&lt;match url="http://*.*" /&gt;
  • @Sam 也许你没有安装 URL Rewrite 模块?默认不自带IIS,需要单独安装。例如。 docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
【解决方案2】:

对于那些使用 ASP.NET MVC 的人。您可以使用 RequireHttpsAttribute 强制所有响应为 HTTPS:

GlobalFilters.Filters.Add(new RequireHttpsAttribute());

您可能还想采取其他措施来帮助保护您的网站:

  1. 强制防伪令牌使用 SSL/TLS:

    AntiForgeryConfig.RequireSsl = true;
    
  2. 通过更改 Web.config 文件要求 Cookie 默认需要 HTTPS:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
    
  3. 使用 NWebSec.Owin NuGet 包并添加以下代码行以启用跨站点的严格传输安全 (HSTS)。不要忘记在下面添加 Preload 指令并将您的网站提交到HSTS Preload site。更多信息herehere。请注意,如果您不使用 OWIN,可以在 NWebSec 站点上阅读 Web.config 方法。

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
    
  4. 使用 NWebSec.Owin NuGet 包并添加以下代码行以在整个站点中启用公钥固定 (HPKP)。更多信息herehere

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHpkp(options => options
        .Sha256Pins(
            "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
            "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
        .MaxAge(days: 30));
    
  5. 在使用的任何 URL 中包含 https 方案。 Content Security Policy (CSP) HTTP 标头和Subresource Integrity (SRI) 在某些浏览器中模仿该方案时效果不佳。最好明确说明 HTTPS。例如

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
    
  6. 使用ASP.NET MVC Boilerplate Visual Studio 项目模板生成一个包含所有这些以及更多内置功能的项目。您还可以在GitHub 上查看代码。

【讨论】:

  • 该问题要求使用 ASP.NET,但没有说明 WebForms 或 MVC,因此我为使用 MVC(不使用 Web.config 文件强制 HTTPS)的人提供了一个全面的答案。 ..downvoted。
  • a) 解决方案有效,但情况发生了变化,这个突出的、高评价的问题值得使用 MVC 内置的内容更新答案。 b)答案试图涵盖所有基础。问题并不简单,在整个站点上启用 HTTPS 需要的不仅仅是更改 web.config 文件。读者可能会误以为只需更改 Web.config 文件即可。安全性已经够难了,因为它没有不完整/过时的答案。
  • 在我看来,这是一个极好的和有价值的答案。当有人在谷歌上搜索该主题并被定向到这个问题时,我很高兴你的答案在这里。
  • @MuhammadRehanSaeed 不错的帖子。也许将 SRI 添加到您的列表中? scotthelme.co.uk/subresource-integrity
  • @MuhammadRehanSaeed 是的 - 我猜您的标题“您可能还想做其他事情来帮助保护您的网站”让我想到了 :)
【解决方案3】:

为了补充 LazyOne 的答案,这里是答案的注释版本。

<rewrite>
  <rules>
     <clear />
     <rule name="Redirect all requests to https" stopProcessing="true">
       <match url="(.*)" />
         <conditions logicalGrouping="MatchAll">
           <add input="{HTTPS}" pattern="off" ignoreCase="true" />
         </conditions>
         <action 
            type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
            redirectType="Permanent" appendQueryString="false" />
     </rule>
  </rules>
</rewrite>

清除可能已在此服务器上定义的所有其他规则。创建一个新规则,我们将其命名为“将所有请求重定向到 https”。处理完这条规则后,不要再处理任何规则了!匹配所有传入的 URL。然后检查是否所有这些其他条件都为真:HTTPS 已关闭。好吧,这只是一个条件(但要确保它是真的)。如果是,请将 301 永久重定向发送回客户端 http://www.foobar.com/whatever?else=the#url-contains。不要在末尾添加查询字符串,因为它会重复查询字符串!

这就是属性、属性和一些值的含义。

  • clear 会移除我们可能会继承的所有服务器规则。
  • rule 定义一个规则。
    • name 规则的任意(虽然是唯一的)名称。
    • stopProcessing 是立即将请求转发到 IIS 请求管道还是首先处理附加规则。
  • 匹配何时运行此规则。
    • url 用于评估 URL 的模式
  • 条件 关于何时运行此规则的附加条件;仅当首先存在匹配时才处理条件。
    • logicalGrouping 是所有条件都必须为真(MatchAll)还是任何条件都必须为真(MatchAny);类似于 AND 与 OR。
  • add 添加一个必须满足的条件。
    • input 条件正在评估的输入;输入可以是服务器变量。
    • pattern 评估输入的标准。
    • ignoreCase 大小写是否重要。
  • action 如果match 及其conditions 都为真,该怎么办。
    • type 通常可以是redirect(客户端)或rewrite(服务器端)。
    • url 这条规则产生的结果;在这种情况下,将 https:// 与两个服务器变量连接起来。
    • redirectType 使用什么 HTTP 重定向;这个是301永久的。
    • appendQueryString 是否在结果url 的末尾添加查询字符串;在这种情况下,我们将其设置为 false,因为 {REQUEST_URI} 已经包含它。

服务器变量是

  • {HTTPS}OFFON
  • {HTTP_HOST}www.mysite.com,并且
  • {REQUEST_URI} 包括 URI 的其余部分,例如/home?key=value
    • 浏览器处理#fragment(参见 LazyOne 的评论)。

另请参阅:https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference

【讨论】:

  • 一个注意事项:URL的片段部分(来自/home?key=value#fragment)没有被浏览器设置到服务器,因为它意味着在本地使用。
  • @LazyOne 问题。我们使用上面的 web.config 成功地从 greenearth.game/about#foo 重定向到 HTTPS。切换到 HTTPS 包括 #foo 片段。鉴于#foo部分没有发送到服务器,重定向如何包含它?
  • 由浏览器处理。只需在 Google Chrome 中打开网络选项卡(或在 Firefox 等中类似),然后查看实际请求的 URL(例如,http://www.example.com/members#oops 请求将发送到 http://www.example.com/members,然后重定向到 https://www.example.com/members 的 HTTPS 版本 - 浏览器确实如此其余的)
  • @LazyOne 谢谢你。如果我没记错的话,有一些 WebKit 错误会阻止片段包含在重定向中。所以,这是有道理的。 bugs.webkit.org/show_bug.cgi?id=24175
  • en.wikipedia.org/wiki/Fragment_identifier -- "客户端在检索文档时不应该向服务器发送 URI 片段,并且没有本地应用程序的帮助(见下文)片段不参与HTTP 重定向” - 只是为了清楚以防我误解了您的最后评论。
【解决方案4】:

接受的答案对我不起作用。 我按照blog 上的步骤操作。

我缺少的一个关键点是我需要下载并安装用于 IIS 的 URL 重写工具。我找到了here 结果如下。

<rewrite>
        <rules>
            <remove name="Http to Https" />
            <rule name="Http to Https" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
                <match url="*" />
                <conditions>
                    <add input="{HTTPS}" pattern="off" />
                </conditions>
                <serverVariables />
                <action type="Redirect" url="https://{HTTPS_HOST}{REQUEST_URI}" />
            </rule>
        </rules>
    </rewrite>

【讨论】:

  • 添加重写工具对我有用。谢谢!
【解决方案5】:

在 .Net Core 中,按照https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl 处的说明进行操作

在您的 startup.cs 中添加以下内容:

// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });`enter code here`

要将Http重定向到Https,在startup.cs中添加以下内容

// Requires using Microsoft.AspNetCore.Rewrite;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    var options = new RewriteOptions()
       .AddRedirectToHttps();

    app.UseRewriter(options);

【讨论】:

    【解决方案6】:

    优秀的NWebsec 库可以使用Web.config 中的upgrade-insecure-requests 标记将您的请求从HTTP 升级到HTTPS:

    <nwebsec>
      <httpHeaderSecurityModule>
        <securityHttpHeaders>
          <content-Security-Policy enabled="true">
            <upgrade-insecure-requests enabled="true"  />
          </content-Security-Policy>
        </securityHttpHeaders>
      </httpHeaderSecurityModule>
    </nwebsec>
    

    【讨论】:

      【解决方案7】:

      我正在使用下面的代码,它非常适合我,希望对你有所帮助。

      <configuration>
      <system.webServer>
          <rewrite>
              <rules>
                  <rule name="Force redirect to https" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions>
                          <add input="{HTTPS}" pattern="^OFF$" />
                      </conditions>
                      <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" />
                  </rule>
              </rules>
          </rewrite>
      </system.webServer>
      

      【讨论】:

        【解决方案8】:

        我的环境不允许安装 URL Rewrite,所以我找到了另一个路径。

        将此添加到我的 web.config 添加了错误重写并在 IIS 7.5 上工作:

        <system.webServer>
            <httpErrors errorMode="Custom" defaultResponseMode="File" defaultPath="C:\WebSites\yoursite\" >    
            <remove statusCode="403" subStatusCode="4" />
            <error statusCode="403" subStatusCode="4" responseMode="File" path="redirectToHttps.html" />
        </httpErrors>
        

        然后,按照这里的建议:https://www.sslshopper.com/iis7-redirect-http-to-https.html

        我将 IIS 网站配置为需要 SSL,并创建了在 403 (Forbidden) 错误时执行重定向 (redirectToHttps.html) 的 html 文件:

        <html>
        <head><title>Redirecting...</title></head>
        <script language="JavaScript">
        function redirectHttpToHttps()
        {
            var httpURL= window.location.hostname + window.location.pathname + window.location.search;
            var httpsURL= "https://" + httpURL;
            window.location = httpsURL;
        }
        redirectHttpToHttps();
        </script>
        <body>
        </body>
        </html>
        

        我希望有人觉得这很有用,因为我在其他任何地方都找不到所有的作品。

        【讨论】:

          【解决方案9】:

          当您在 AWS 上使用带有应用程序负载均衡器的 IIS 10 时,您必须如下配置重定向。

                  <rule name="Force HTTPS" enabled="true" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                          <add input="{HTTP_X_Forwarded_Proto}" pattern="^https$" negate="true" />
                          <add input="{HTTP_HOST}" pattern="^(www\.)?dname\.com$" />
                      </conditions>
                      <action type="Redirect" url="https://www.dname.com{REQUEST_URI}" />
                  </rule>
          

          如果您有子域重定向,请使用以下:

                  <!--START REDIRECT TO HTTPS-->
                  <rule name="Force HTTPS" enabled="true" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                          <add input="{HTTP_X_Forwarded_Proto}" pattern="^https$" negate="true" />
                          <add input="{HTTP_HOST}" pattern="subdomain\.domain\.com$" />
                      </conditions>
                      <action type="Redirect" url="https://subdomain.domain.com{REQUEST_URI}" />
                  </rule> 
                  <!--END REDIRECT TO HTTPS-->    
          

          【讨论】:

            【解决方案10】:

            简单的方法是告诉 IIS 为 HTTP 请求发送您的自定义错误文件。然后该文件可以包含元重定向、JavaScript 重定向和带有链接的说明等...重要的是,您仍然可以为站点(或文件夹)选中“需要 SSL”,这将起作用。

            </configuration>
            </system.webServer>
                <httpErrors>
                    <clear/>
                    <!--redirect if connected without SSL-->
                    <error statusCode="403" subStatusCode="4" path="errors\403.4_requiressl.html" responseMode="File"/>
                </httpErrors>
            </system.webServer>
            </configuration>
            

            【讨论】:

            • 为什么投反对票?它有效并回答了问题。
            • 这是一个反对票,因为您告诉 Google 找不到您的文件,然后您使用 JavaScript 进行重定向,这通常很糟糕。
            猜你喜欢
            • 2021-04-12
            • 1970-01-01
            • 2013-01-28
            • 2016-01-31
            • 2017-03-30
            • 2012-03-03
            • 2017-07-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多