在asp.net强制https整个网站的最佳途径?

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

有没有更好的方法 – 理想情况下在web.config中的一些设置?

请使用HSTS

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> 

原始答复

基本上

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

这将在global.asax.cs(或global.asax.vb)

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

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

 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。

IIS7模块将让你redirect。

  <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> 

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

艰难的路

1 – 将RequireHttpsAttribute添加到全局filter:

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

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

 AntiForgeryConfig.RequireSsl = true; 

3 – 要求Cookie通过更改Web.config文件来默认要求HTTPS:

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

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 – 使用NWebSec.Owin NuGet程序包并添加以下代码行以在整个站点上启用公用密钥locking(HPKP)。 更多信息在这里和这里 。

 // app is your OWIN IAppBuilder app in Startup.cs app.UseHpkp(options => options .Sha256Pins( "Base64 encoded SHA-256 hash of your first certificate eg cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=", "Base64 encoded SHA-256 hash of your second backup certificate eg M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=") .MaxAge(days: 30)); 

6 – 将httpsscheme包含在任何使用的URL中。 内容安全策略(CSP) HTTP头和子资源完整性(SRI)在您在某些浏览器中模仿该scheme时效果不佳 。 明确HTTPS更好。 例如

 <script src="ajax/bootstrap/3.3.4/bootstrap.min.js"></script> 

简单的方法

使用ASP.NET MVC Boilerplate Visual Studio项目模板生成一个包含所有这些内置项目的项目。您还可以在GitHub上查看代码。

如果你不能在任何原因在IIS中设置它,我会做一个HTTP模块为你做redirect:

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

然后把它编译成一个DLL文件,把它作为参考添加到你的项目中,并把它放在web.config中:

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

你需要做的是:

1)在web.config中添加一个密钥,具体取决于下面的生产或阶段服务器

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

这也取决于您的平衡器的品牌,对于networking多路复用器,您需要查找http标头X-WebMux-SSL-termination: true来确定传入stream量是否为ssl。 详细信息在这里: http : //www.cainetworks.com/support/redirect2ssl.html

如果SSL支持在您的站点中是不可configuration的(即,应该能够打开/closureshttps) – 您可以在您希望保护的任何控制器/控制器操作上使用[RequireHttps]属性。

对于上面的@Joe,“这是给我一个redirect循环。在我添加代码之前,它工作得很好。有什么build议? – 乔11月8日11日在4:13”

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

我承认这有点冒险,但是对我来说有效的是实现一个“JustRedirected”属性,我可以利用这个属性来弄清楚这个人已经被redirect了一次。 所以,我testing的redirect的具体条件,如果他们符合,我在redirect之前设置此属性(存储在会话中的值)。 即使第二次满足redirect的http / https条件,我也会绕过redirect逻辑并将“JustRedirected”会话值重置为false。 你将需要你自己的条件testing逻辑,但是这里有一个简单的属性实现:

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

我打算把我的两分钱。 如果你有访问IIS服务器端,那么你可以通过使用协议绑定强制HTTPS。 例如,您有一个名为Blah的网站。 在IIS中,您将设置两个站点: BlahBlah(redirect) 。 对于Blah,只能configurationHTTPS绑定(如果需要,还可以使用FTP ,确保也通过安全连接强制执行)。 对于Blah(redirect),只configurationHTTP绑定。 最后,在Blah(redirect)HTTPredirect部分中,确保将301redirect设置为https://blah.com ,并启用确切的目的地。 确保IIS中的每个站点都指向它自己的根文件夹,否则Web.config将全部搞砸。 另外,请确保在HTTPSed站点上configuration了HSTS ,以便浏览器的后续请求始终强制为HTTPS,并且不会发生redirect。

– >在公共类HomeController:Controller上简单地添加[RequireHttps]。

– >并添加GlobalFilters.Filters.Add(新的RequireHttpsAttribute()); 在Global.asax.cs文件的'protected void Application_Start()'方法中。

这将强制您的整个应用程序使用HTTPS。

这是基于@Troy Hunt的更全面的答案。 将此函数添加到Global.asax.csWebApplication类中:

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

(要在本地构build中启用SSL,请在项目的“属性”对话框中启用它)

如果您正在使用ASP.NET Core,则可以尝试使用nuget包SaidOut.AspNetCore.HttpsWithStrictTransportSecurity。

那么你只需要添加

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

这也会将HTTP StrictTransportSecurity标头添加到使用httpsscheme进行的所有请求。

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

http模块的另一个优点是,如果你只在global.asax.cs中提供它,它只在Application_BeginRequest上检查SSL,这意味着你的应用程序没有被完全保护。 它只会首先路由到SSL版本,然后用户可以剪切和粘贴没有SSL的URL并绕过它。