Около 6 месяцев назад я развернул сайт, на котором все запросы должны были выполняться через https. Единственный способ в то время, который я мог найти, гарантировать, что каждый запрос к странице был через https, - это проверить его в событии загрузки страницы. Если бы запрос не превышал http, я бы ответил: response.redirect ("https://example.com")
Есть ли способ лучше - в идеале какие-то настройки в web.config?
Связанный пост - Как заставить HTTPS использовать файл web.config





Пожалуйста, используйте HSTS (HTTP Strict Transport Security)
от 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>
Оригинальный ответ (заменено на вышеуказанное 4 декабря 2015 г.)
по сути
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
Это работает, но для меня это было опасно: когда я пытался запустить локально в VS 2010 с этим кодом, моя стартовая страница не загружалась; вместо этого я только что получил сообщение «Эта веб-страница недоступна». Чтобы исправить это, я добавил второе условие, чтобы проверить, содержит ли URL-адрес строку «localhost»: если нет, то принудительно используйте https.
Это дает мне цикл перенаправления. До того, как я добавил код, он работал нормально. Какие-либо предложения?
+1, он делает перенаправление на сервер дважды? Во-первых, когда вы явно перенаправляете, а во-вторых, когда вы выполняете перенаправление в Global.asax?
Обратите внимание, что это не обеспечивает никакой полезной безопасности. Фактически, он будет защищать соединения только от пользователей, которые уже находятся в безопасности, и не сможет защитить тех, кто подвергается атаке (это потому, что MITM может просто полностью опустить перенаправление и перенаправить все на ваш «безопасный» сайт). ИМХО, перенаправление пользовательских агентов - это просто приятная защита вуду, которая дает иногда опасную иллюзию безопасности. Единственный выход - указать пользовательским агентам запрашивать только защищенные ресурсы, а не перенаправлять их, если они этого не делают. Это то, что делает HSTS - см. Ответы ниже.
Вы также можете добавить - «GlobalFilters.Filters.Add (новый RequireHttpsAttribute ());» к методу Application_Start () в global.asax.cs
Этот ответ следует считать «вредным», и его не следует использовать. Согласно комментарию @tne выше.
Если вы получаете сообщение об ошибке о том, что ваш web.config неправильно сформирован, убедитесь, что у вас установлен модуль перезаписи URL - из-за этого я застрял на 10 минут или около того. iis.net/downloads/microsoft/url-rewrite
@RosdiKasim Должен ли этот ответ по-прежнему считаться вредным после редактирования 4 декабря 2015 года?
@AndrewMorton Обновленный ответ (с использованием HSTS) - правильный способ сделать это. Он также перенаправляет браузер на https, если браузер использует http.
У меня это не работает. Сайт никогда не перенаправляется. Я отредактировал свой web.config, как указано выше. Сайт отлично работает без редактирования web.config, а сайт https работает нормально, если я перейду прямо туда (при условии отсутствия изменений в web.config). У кого-нибудь еще были проблемы с этим кодом?
У меня другая проблема. Нет перенаправления, но я не могу попасть на сайт https независимо от того, обновлен ли я web.config или нет. firefox говорит SSL_ERROR_RX_RECORD_TOO_LONG, а IE говорит, чтобы включить TLS 1, 1.1 и 1.2 и повторить попытку.
Мне всегда приходилось использовать <add input = "{HTTPS}" pattern = "on" negate = "true" />, потому что off никогда не работал. Может быть, сейчас, я даже не пробую сейчас.
Я скопировал эту строку в свой web.config, и теперь https не работает. Я удалил эти строки из web.config, но мой сайт по-прежнему не работает. Мне кажется, что эти несколько строк что-то изменили в моей системе, связанной с этим проектом.
После включения hsts для домена браузер не разрешит незащищенное соединение. Вам нужно либо настроить https, либо очистить hsts для домена в вашем браузере.
Если вы не можете настроить это в 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
}
}
}
Затем просто скомпилируйте его в DLL, добавьте в качестве ссылки на свой проект и поместите в web.config:
<httpModules>
<add name = "HttpsOnlyModule" type = "HttpsOnly.HttpsOnlyModule, HttpsOnly" />
</httpModules>
Это кажется более сложным, чем просто вставить его в global.asax - просто любопытно, есть ли в этом преимущество?
Преимущество состоит в том, что если вы не хотите его использовать, просто закомментируйте модуль в своем web.config. Это решение является настраивается, а другое - нет.
Я немного запутался. Я ожидал, что в методе app.BeginRequest += new OnBeginRequest; будет что-то вроде Init, а в OnBeginRequest будет содержаться то, что содержится в текущем методе Init. Вы уверены, что этот модуль работает должным образом?
Это не работает. Вам нужно добавить событие OnBeginRequest и т. д., Тогда оно сработает.
Я бы отредактировал этот ошибочный код, но чтобы сделать его безопасным, вам также нужно будет использовать HSTS. Просто воспользуйтесь ответом Троя Ханта и сделайте его модулем; см. support.microsoft.com/en-us/kb/307996 (старый, но хороший).
Модуль 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>
Кроме того, для IIS 7.0 необходимо установить модуль переопределения URL-адресов 2.0.
Я нашел эту ссылку простой и полезной для того, чтобы любая конкретная страница принимала только запросы https - support.microsoft.com/kb/239875
Это также зависит от марки вашего балансировщика, для веб-мультиплексора вам нужно будет искать http-заголовок X-WebMux-SSL-termination: true, чтобы определить, что входящий трафик был ssl. подробности здесь: http://www.cainetworks.com/support/redirect2ssl.html
Еще вы можете использовать HSTS, вернув браузеру заголовок «Strict-Transport-Security». Браузер должен поддерживать это (и в настоящее время это делают в первую очередь 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.
Никогда раньше не слышал о заголовке HSTS, но выглядит довольно круто. Есть ли причина использовать такое маленькое значение максимального возраста (5 минут)? В статье в Википедии, на которую вы ссылаетесь, предлагается установить для него большое значение (6–12 месяцев).
+1. ознакомьтесь с этой очень обширной статьей в блоге Троя, в которой подробно рассказывается, почему только использование перенаправления может снизить безопасность. Подсказка: среди прочего, это может сделать вас уязвимыми для инструмента SSL Strip. troyhunt.com/2011/11/…
Также стоит проверить NWebsec, который делает это (и многое другое) очень простым.
Вы захотите обернуть переключатель в if (!Request.IsLocal), чтобы он не мешал отладке.
Хороший ответ. Одна тонкость - для заголовков Http («Strict-Transport-Security») лучше использовать такую библиотеку, как NWebSec, потому что есть несколько параметров, которые сосредоточены в одном месте конфигурации, а не разбросаны здесь и там.
@RosdiKasim, принятый ответ был обновлен и для HSTS, но полностью исключил "старый ответ", который показывал только перенаправление в коде. Это хорошо для того, чтобы делать это в коде. Также может быть записан в IHttpModule.
Быстрое преобразование в VB.net, и это решение отлично работало.
Из-за пары нетехнических проблем я использовал этот метод ... за исключением того, что я возвращаю «308 Permanent Redirect», который гарантирует, что POST остаются POST для перенаправления http.
Сначала я использовал предложение montys использовать 308 вместо 301 из-за поддержки POST, только чтобы узнать, что 308 не поддерживается IE11. Если значительная часть ваших посетителей все еще пользуется IE, это может быть проблемой.
Обрабатывает ли это весь трафик на этот веб-сайт? или только страницы, которые вы закодировали? То есть как насчет моих изображений и файлов javascript?
Для @Joe выше: «Это дает мне цикл перенаправления. До того, как я добавил код, он работал нормально. Есть предложения? - Джо, 8 ноября 2011 г., 16:13»
Это происходило и со мной, и, как я полагаю, происходило то, что балансировщик нагрузки завершал запрос SSL перед веб-сервером. Итак, мой веб-сайт всегда думал, что запрос был «http», даже если исходный браузер запрашивал «https».
Я признаю, что это немного взломано, но что сработало для меня, так это реализация свойства 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;
}
}
Если поддержка SSL не настраивается на вашем сайте (т. Е. Должна иметь возможность включать / отключать https), вы можете использовать атрибут [RequireHttps] для любого действия контроллера / контроллера, которое вы хотите защитить.
Что вам нужно сделать:
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);
}
}
}
}
Для тех, кто использует ASP.NET MVC. Вы можете использовать следующее, чтобы принудительно использовать SSL / TLS через HTTPS для всего сайта двумя способами:
Трудный путь
1 - Добавьте RequireHttpsAttribute к глобальным фильтрам:
GlobalFilters.Filters.Add(new RequireHttpsAttribute());
2 - Заставить токены Anti-Forgery использовать SSL / TLS:
AntiForgeryConfig.RequireSsl = true;
3 - Требовать, чтобы файлы cookie требовали HTTPS по умолчанию, изменив файл Web.config:
<system.web>
<httpCookies httpOnlyCookies = "true" requireSSL = "true" />
</system.web>
4 - Используйте пакет NWebSec.Owin NuGet и добавьте следующую строку кода, чтобы включить строгую транспортную безопасность на сайте. Не забудьте добавить директиву Preload ниже и отправить свой сайт в Сайт предварительной загрузки HSTS. Дополнительная информация здесь и здесь. Обратите внимание: если вы не используете OWIN, существует метод Web.config, о котором вы можете прочитать на сайте NWebSec.
// app is your OWIN IAppBuilder app in Startup.cs
app.UseHsts(options => options.MaxAge(days: 30).Preload());
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 - Включите схему https в любой используемый URL. Заголовок HTTP Политика безопасности контента (CSP) и Целостность подресурсов (SRI) не работают хорошо, когда вы имитируете схему в некоторых браузерах. О HTTPS лучше прямо сказать. например
<script src = "https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>
Легкий путь
Используйте шаблон проекта Шаблон ASP.NET MVC Visual Studio, чтобы создать проект со всем этим и многим другим встроенным. Вы также можете просмотреть код на GitHub.
Также, если вы используете <authentication mode = "Forms">, внутри у вас должен быть <forms requireSSL = "true">
@ muhammad-rehan-saeed Я использую шаблон mvc5, но сайт не перенаправляет http на https автоматически на производственном сервере, это происходит только на localhost, есть ли что-то, чего мне не хватает?
Это не тот форум, чтобы задавать этот вопрос. Опубликуйте вопрос на сайте GitHub. RequireHttpsAttribute выполняет перенаправление. Пока он у вас есть, все должно быть в порядке.
@MuhammadRehanSaeed, люблю твой ответ. Но ... как мне получить хэш SHA256 сертификата, созданного с помощью MakeCert? Все, что у меня есть, - это отпечаток пальца SHA-1 ... Вы случайно не знаете?
Ссылка @Diana это может показать вам, как это сделать.
Я собираюсь бросить свои два цента. ЕСЛИ у вас есть доступ к стороне сервера IIS, тогда вы можете принудительно использовать HTTPS, используя привязки протокола. Например, у вас есть веб-сайт Бла. В IIS вы должны настроить два сайта: Бла и Бла (перенаправление). Для Бла настройте только привязку HTTPS (и FTP, если вам нужно, убедитесь, что это принудительно выполнено через безопасное соединение). Для Бла (перенаправление) настройте только привязку HTTP. Наконец, в разделе Перенаправление HTTP для Бла (перенаправление) не забудьте установить 301 перенаправление на https://blah.com с включенным точным местом назначения. Убедитесь, что каждый сайт в IIS указывает на свою корневую папку собственный, иначе Web.config все испортится. Также убедитесь, что на вашем HTTPS-сайте настроен HSTS, чтобы последующие запросы браузера всегда были принудительно отправлены на HTTPS и никаких перенаправлений не происходило.
-> Просто добавьте [RequireHttps] поверх открытого класса HomeController: Controller.
-> И добавить GlobalFilters.Filters.Add (новый RequireHttpsAttribute ()); в методе protected void Application_Start () в файле Global.asax.cs.
Это заставляет все ваше приложение использовать HTTPS.
Я не верю, что это сработает для любых страниц, обслуживаемых с помощью WebForms или любых API, созданных с помощью WebAPI. Он будет охватывать только контроллеры MVC.
Это более полный ответ, основанный на @Troy Hunt. Добавьте эту функцию в свой класс WebApplication в Global.asax.cs:
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 в вашей локальной сборке, включите его в панели свойств проекта)
Если вы используете ASP.NET Core, вы можете попробовать пакет nuget SaidOut.AspNetCore.HttpsWithStrictTransportSecurity.
Тогда вам нужно только добавить
app.UseHttpsWithHsts(HttpsMode.AllowedRedirectForGet, configureRoutes: routeAction);
Это также добавит заголовок HTTP StrictTransportSecurity ко всем запросам, сделанным с использованием схемы https.
Пример кода и документация https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code
Я потратил какое-то время на поиски лучших практик, которые имели бы смысл, и нашел следующее, которое сработало для меня. Надеюсь, это когда-нибудь тебя спасет.
Использование Файл конфигурации (например, сайт asp.net) https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/
или на вашем собственном сервере https://www.sslshopper.com/iis7-redirect-http-to-https.html
[КРАТКИЙ ОТВЕТ] Просто Код ниже находится внутри
<system.webServer>
<rewrite>
<rules>
<rule name = "HTTP/S to HTTPS Redirect" enabled = "true"
stopProcessing = "true">
<match url = "(.*)" />
<conditions logicalGrouping = "MatchAny">
<add input = "{SERVER_PORT_SECURE}" pattern = "^0$" />
</conditions>
<action type = "Redirect" url = "https://{HTTP_HOST}{REQUEST_URI}"
redirectType = "Permanent" />
</rule>
</rules>
</rewrite>
В IIS10 (Windows 10 и Server 2016), начиная с версии 1709, есть новый, более простой вариант включения HSTS для веб-сайта.
Microsoft описывает преимущества нового подхода здесь и предоставляет множество различных примеров того, как реализовать изменение программно или путем прямого редактирования файла ApplicationHost.config (который похож на web.config, но работает на уровне IIS, а не на уровне отдельного сайта. ). ApplicationHost.config можно найти в C: \ Windows \ System32 \ inetsrv \ config.
Я описал здесь два примера методов, чтобы избежать гниения ссылок.
Способ 1 - напрямую редактировать файл ApplicationHost.config
Между тегами <site> добавьте эту строку:
<hsts enabled = "true" max-age = "31536000" includeSubDomains = "true" redirectHttpToHttps = "true" />
Способ 2 - Командная строка: Выполните следующее из командной строки с повышенными привилегиями (т.е. правой кнопкой мыши на CMD и запустите от имени администратора). Не забудьте заменить Contoso на имя вашего сайта, как оно отображается в диспетчере IIS.
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
Другие методы, предлагаемые Microsoft в этих статьях, могут быть лучшими вариантами, если вы находитесь в размещенной среде, к которой у вас ограниченный доступ.
Имейте в виду, что IIS10 версии 1709 сейчас доступен в Windows 10, но для Windows Server 2016 он находится на другом треке выпуска и не будет выпущен в виде исправления или пакета обновления. Подробнее о 1709 см. здесь.
проверьте мой ответ здесь stackoverflow.com/questions/33882350/…