C# asp.net 中为整个站点强制使用 https 的最佳方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 09:58:53  来源:igfitidea点击:

Best way in asp.net to force https for an entire site?

提问by codethrift

About 6 months ago I rolled out a site where every request needed to be over https. The only way at the time I could find to ensure that every request to a page was over https was to check it in the page load event. If the request was not over http I would response.redirect("https://example.com")

大约 6 个月前,我推出了一个网站,每个请求都需要通过 https。当时我能找到的确保每个页面请求都通过 https 的唯一方法是在页面加载事件中检查它。如果请求不是通过 http 我会 response.redirect(" https://example.com")

Is there a better way -- ideally some setting in the web.config?

有没有更好的方法——最好在 web.config 中进行一些设置?

采纳答案by John Boker

Please use HSTS(HTTP Strict Transport Security)

请使用HSTS(HTTP 严格传输安全)

from http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx

来自http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <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>
    </system.webServer>
</configuration>

Original Answer(replaced with the above on 4 December 2015)

原始答案(2015 年 12 月 4 日替换为上述内容)

basically

基本上

protected void Application_BeginRequest(Object sender, EventArgs e)
{
   if (HttpContext.Current.Request.IsSecureConnection.Equals(false) && HttpContext.Current.Request.IsLocal.Equals(false))
   {
    Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"]
+   HttpContext.Current.Request.RawUrl);
   }
}

that would go in the global.asax.cs (or global.asax.vb)

这将进入 global.asax.cs(或 global.asax.vb)

i dont know of a way to specify it in the web.config

我不知道在 web.config 中指定它的方法

回答by FlySwat

If you are unable to set this up in IIS for whatever reason, I'd make an HTTP module that does the redirect for you:

如果由于某种原因您无法在 IIS 中进行设置,我会制作一个 HTTP 模块来为您进行重定向:

using System;
using System.Web;

namespace HttpsOnly
{
    /// <summary>
    /// Redirects the Request to HTTPS if it comes in on an insecure channel.
    /// </summary>
    public class HttpsOnlyModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Note we cannot trust IsSecureConnection when 
            // in a webfarm, because usually only the load balancer 
            // will come in on a secure port the request will be then 
            // internally redirected to local machine on a specified port.

            // Move this to a config file, if your behind a farm, 
            // set this to the local port used internally.
            int specialPort = 443;

            if (!app.Context.Request.IsSecureConnection 
               || app.Context.Request.Url.Port != specialPort)
            {
               app.Context.Response.Redirect("https://" 
                  + app.Context.Request.ServerVariables["HTTP_HOST"] 
                  + app.Context.Request.RawUrl);    
            }
        }

        public void Dispose()
        {
            // Needed for IHttpModule
        }
    }
}

Then just compile it to a DLL, add it as a reference to your project and place this in web.config:

然后只需将其编译为 DLL,将其添加为对您的项目的引用并将其放置在 web.config 中:

 <httpModules>
      <add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" />
 </httpModules>

回答by Mark

The IIS7 module will let you redirect.

IIS7 模块将让您重定向。

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

回答by Alexander

It also depends on the brand of your balancer, for the web mux, you would need to look for http header X-WebMux-SSL-termination: trueto figure that incoming traffic was ssl. details here: http://www.cainetworks.com/support/redirect2ssl.html

它还取决于您的平衡器的品牌,对于网络复用器,您需要查找 http 标头来X-WebMux-SSL-termination: true确定传入流量是 ssl。详情请见:http: //www.cainetworks.com/support/redirect2ssl.html

回答by Troy Hunt

The other thing you can do is use HSTSby returning the "Strict-Transport-Security" header to the browser. The browser has to support this (and at present, it's primarily Chrome and Firefox that do), but it means that once set, the browser won't make requests to the site over HTTP and will instead translate them to HTTPS requests before issuing them. Try this in combination with a redirect from HTTP:

您可以做的另一件事是通过将“Strict-Transport-Security”标头返回给浏览器来使用HSTS。浏览器必须支持这一点(目前主要是 Chrome 和 Firefox 支持),但这意味着一旦设置,浏览器将不会通过 HTTP 向站点发出请求,而是在发出请求之前将它们转换为 HTTPS 请求. 结合 HTTP 重定向试试这个:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
  switch (Request.Url.Scheme)
  {
    case "https":
      Response.AddHeader("Strict-Transport-Security", "max-age=300");
      break;
    case "http":
      var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
      Response.Status = "301 Moved Permanently";
      Response.AddHeader("Location", path);
      break;
  }
}

Browsers that aren't HSTS aware will just ignore the header but will still get caught by the switch statement and sent over to HTTPS.

不支持 HSTS 的浏览器只会忽略标头,但仍会被 switch 语句捕获并发送到 HTTPS。

回答by Paul Schroeder

For @Joe above, "This is giving me a redirect loop. Before I added the code it worked fine. Any suggestions? – Joe Nov 8 '11 at 4:13"

对于上面的@Joe,“这给了我一个重定向循环。在我添加代码之前它运行良好。有什么建议吗? – Joe 2011 年 11 月 8 日 4:13”

This was happening to me as well and what I believe was happening is that there was a load balancer terminating the SSL request in front of the Web server. So, my Web site was always thinking the request was "http", even if the original browser requested it to be "https".

这也发生在我身上,我相信正在发生的是有一个负载平衡器在 Web 服务器前面终止 SSL 请求。所以,我的网站总是认为请求是“http”,即使原始浏览器请求它是“https”。

I admit this is a bit hacky, but what worked for me was to implement a "JustRedirected" property that I could leverage to figure out the person was already redirected once. So, I test for specific conditions that warrant the redirect and, if they are met, I set this property (value stored in session) prior to the redirection. Even if the http/https conditions for redirection are met the second time, I bypass the redirection logic and reset the "JustRedirected" session value to false. You'll need your own conditional test logic, but here's a simple implementation of the property:

我承认这有点 hacky,但对我有用的是实现一个“JustRedirected”属性,我可以利用它来确定这个人已经被重定向过一次。因此,我测试了保证重定向的特定条件,如果满足这些条件,我会在重定向之前设置此属性(存储在会话中的值)。即使第二次满足重定向的 http/https 条件,我也会绕过重定向逻辑并将“JustRedirected”会话值重置为 false。您将需要自己的条件测试逻辑,但这里有一个简单的属性实现:

    public bool JustRedirected
    {
        get
        {
            if (Session[RosadaConst.JUSTREDIRECTED] == null)
                return false;

            return (bool)Session[RosadaConst.JUSTREDIRECTED];
        }
        set
        {
            Session[RosadaConst.JUSTREDIRECTED] = value;
        }
    }

回答by yarg

If SSL support is not configurable in your site (ie. should be able to turn https on/off) - you can use the [RequireHttps] attribute on any controller / controller action you wish to secure.

如果您的站点中无法配置 SSL 支持(即应该能够打开/关闭 https) - 您可以在您希望保护的任何控制器/控制器操作上使用 [RequireHttps] 属性。

回答by Chandan Kumar

What you need to do is :

你需要做的是:

1) Add a key inside of web.config, depending upon the production or stage server like below

1) 在 web.config 中添加一个密钥,具体取决于生产或舞台服务器,如下所示

<add key="HttpsServer" value="stage"/>
             or
<add key="HttpsServer" value="prod"/>

2) Inside your Global.asax file add below method.

2) 在 Global.asax 文件中添加以下方法。

void Application_BeginRequest(Object sender, EventArgs e)
{
    //if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "prod")
    if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "stage")
    {
        if (!HttpContext.Current.Request.IsSecureConnection)
        {
            if (!Request.Url.GetLeftPart(UriPartial.Authority).Contains("www"))
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://www."), true);
            }
            else
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://"), true);
            }
        }
    }
}

回答by Muhammad Rehan Saeed

For those using ASP.NET MVC. You can use the following to force SSL/TLS over HTTPS over the whole site in two ways:

对于那些使用 ASP.NET MVC 的人。您可以使用以下两种方式在整个站点上通过 HTTPS 强制使用 SSL/TLS:

The Hard Way

艰难的道路

1 - Add the RequireHttpsAttribute to the global filters:

1 - 将 RequireHttpsAttribute 添加到全局过滤器:

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

2 - Force Anti-Forgery tokens to use SSL/TLS:

2 - 强制防伪令牌使用 SSL/TLS:

AntiForgeryConfig.RequireSsl = true;

3 - Require Cookies to require HTTPS by default by changing the Web.config file:

3 - 通过更改 Web.config 文件,默认情况下需要 Cookie 需要 HTTPS:

<system.web>
    <httpCookies httpOnlyCookies="true" requireSSL="true" />
</system.web>

4 - Use the NWebSec.Owin NuGet package and add the following line of code to enable Strict Transport Security accross the site. Don't forget to add the Preload directive below and submit your site to the HSTS Preload site. More information hereand here. Note that if you are not using OWIN, there is a Web.config method you can read up on on the NWebSecsite.

4 - 使用 NWebSec.Owin NuGet 包并添加以下代码行以启用跨站点的严格传输安全。不要忘记添加下面的 Preload 指令并将您的站点提交到HSTS Preload 站点。更多信息在这里这里。请注意,如果您没有使用 OWIN,则可以在NWebSec站点上阅读 Web.config 方法。

// app is your OWIN IAppBuilder app in Startup.cs
app.UseHsts(options => options.MaxAge(days: 30).Preload());

5 - Use the NWebSec.Owin NuGet package and add the following line of code to enable Public Key Pinning (HPKP) across the site. More information hereand here.

5 - 使用 NWebSec.Owin NuGet 包并添加以下代码行以启用整个站点的公钥固定 (HPKP)。更多信息在这里这里

// 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));

6 - Include the https scheme in any URL's used. Content Security Policy (CSP)HTTP header and Subresource Integrity (SRI)do not play nice when you imit the scheme in some browsers. It is better to be explicit about HTTPS. e.g.

6 - 在使用的​​任何 URL 中包含 https 方案。当您在某些浏览器中模仿该方案时,内容安全策略 (CSP)HTTP 标头和子资源完整性 (SRI) 效果不佳。最好明确说明 HTTPS。例如

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>

The Easy Way

简单的方法

Use the ASP.NET MVC BoilerplateVisual Studio project template to generate a project with all of this and much more built in. You can also view the code on GitHub.

使用ASP.NET MVC BoilerplateVisual Studio 项目模板生成包含所有这些以及更多内置功能的项目。您还可以在GitHub 上查看代码。

回答by Gup3rSuR4c

I'm going to throw my two cents in. IFyou have access to IIS server side, then you can force HTTPS by use of the protocol bindings. For example, you have a website called Blah. In IIS you'd setup two sites: Blah, and Blah (Redirect). For Blahonly configure the HTTPSbinding (and FTPif you need to, make sure to force it over a secure connection as well). For Blah (Redirect)only configure the HTTPbinding. Lastly, in the HTTP Redirectsection for Blah (Redirect)make sure to set a 301 redirect to https://blah.com, with exact destination enabled. Make sure that each site in IIS is pointing to it's ownroot folder otherwise the Web.configwill get all screwed up. Also make sure to have HSTSconfigured on your HTTPSed site so that subsequent requests by the browser are always forced to HTTPS and no redirects occur.

我将投入我的两分钱。如果您可以访问 IIS 服务器端,那么您可以通过使用协议绑定来强制使用 HTTPS。例如,您有一个名为Blah的网站。在 IIS 中,您将设置两个站点:BlahBlah (Redirect)。对于Blah仅配置HTTPS绑定(FTP如果需要,请确保也通过安全连接强制它)。对于Blah(重定向),仅配置HTTP绑定。最后,在Blah(重定向)HTTP 重定向部分,确保将 301 重定向设置为,并启用精确目标。确保 IIS 中的每个站点都指向它的https://blah.com自己的根文件夹,否则Web.config将全部搞砸。还要确保HSTS在您的 HTTPS 站点上进行了配置,以便浏览器的后续请求始终强制为 HTTPS,并且不会发生重定向。