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

有没有更好的方法,比如web。config中的一些设置?


当前回答

您还可以通过向浏览器返回“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;
  }
}

不了解HSTS的浏览器将忽略头文件,但仍然会被switch语句捕获并发送到HTTPS。

其他回答

对于上面的@Joe,“这是给我一个重定向循环。在我添加代码之前,它工作得很好。有什么建议吗?——乔11月8日11月4点13分

这种情况也发生在我身上,我认为发生的情况是有一个负载均衡器在Web服务器前终止SSL请求。因此,我的Web站点总是认为请求是“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:

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

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

在IIS10 (Windows 10和Server 2016)中,从1709版本开始,有一个新的、更简单的选项可以为网站启用HSTS。

微软在这里描述了新方法的优点,并提供了许多不同的示例,说明如何通过编程或直接编辑ApplicationHost实现更改。配置文件(类似web。配置,但操作在IIS级别,而不是个别站点级别)。ApplicationHost。config可以在c:\ windows \ system32 \inetsrv\config目录下找到。

我在这里概述了避免链接失效的两个示例方法。

方法1 -编辑ApplicationHost。配置文件 在<site>标签之间,添加这一行:

<hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" />

方法2—命令行: 从升高的命令提示符(即在CMD上用鼠标右键并以管理员身份运行)执行以下命令。请记住在IIS管理器中显示的站点名称与Contoso交换。

c:
cd C:\WINDOWS\system32\inetsrv\
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.enabled:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.max-age:31536000" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.includeSubDomains:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.redirectHttpToHttps:True" /commit:apphost

如果您处于访问受限的托管环境中,那么微软在文章中提供的其他方法可能是更好的选择。

请记住,IIS10版本1709现在可以在Windows 10上使用,但对于Windows Server 2016,它在不同的发布轨道上,并且不会作为补丁或服务包发布。点击这里了解1709年的详细信息。

如果您正在使用ASP。你可以试试这个包:赛达。aspnetcore . httpwithstricttransport security。

然后你只需要加

app.UseHttpsWithHsts(HttpsMode.AllowedRedirectForGet, configureRoutes: routeAction);

这也会将HTTP StrictTransportSecurity头添加到所有使用https方案的请求中。

示例代码和文档https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code

你需要做的是:

1)在web中添加一个键。配置,取决于生产或阶段服务器如下所示

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

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

这是基于@特洛伊·亨特的更全面的回答。将这个函数添加到Global.asax.cs中的WebApplication类中:

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // Allow https pages in debugging
        if (Request.IsLocal)
        {
            if (Request.Url.Scheme == "http")
            {
                int localSslPort = 44362; // Your local IIS port for HTTPS

                var path = "https://" + Request.Url.Host + ":" + localSslPort + Request.Url.PathAndQuery;

                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", path);
            }
        }
        else
        {
            switch (Request.Url.Scheme)
            {
                case "https":
                    Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
                    break;
                case "http":
                    var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
                    Response.Status = "301 Moved Permanently";
                    Response.AddHeader("Location", path);
                    break;
            }
        }
    }

(要在本地构建中启用SSL,请在项目的Properties dock中启用它)