Как заставить HTTPS использовать файл web.config

220

Я искал вокруг Google и StackOverflow, пытаясь найти решение этой проблемы, но все они, похоже, относятся к ASP.NET и т. Д.

Я обычно запускаю Linux на своих серверах, но для этого одного клиента я использую Windows с IIS 7.5 (и Plesk 10). Именно поэтому я немного незнаком с файлами IIS и web.config . В .htaccessфайле вы можете использовать условия перезаписи, чтобы определить, является ли протокол HTTPS, и соответственно перенаправить. Есть ли простой способ добиться этого с помощью файла web.config или даже с помощью установленного мной модуля ' URL Rewrite '?

У меня нет опыта работы с ASP.NET, поэтому, если это связано с решением, пожалуйста, включите четкие шаги по реализации.

Причина, по которой я делаю это с web.config, а не с PHP, заключается в том, что я хотел бы использовать HTTPS для всех ресурсов сайта.

Бен Кэри
источник

Ответы:

427

Вам нужен модуль перезаписи URL, предпочтительно v2 (у меня не установлен v1, поэтому я не могу гарантировать, что он будет работать там, но должен).

Вот пример такого web.config - он заставит HTTPS для ВСЕХ ресурсов (используя 301 Permanent Redirect):

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

PS Это конкретное решение не имеет ничего общего с ASP.NET/PHP или любой другой технологией, поскольку оно выполняется только с использованием модуля перезаписи URL - оно обрабатывается на одном из начальных / более низких уровней - до того, как запрос достигнет точки, где ваш код исполняется.

LazyOne
источник
6
@BenCarey Вы также должны посмотреть на Strict-Transport-Securityзаголовок: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne
22
Я рекомендую изменить перенаправление, чтобы оно не добавляло строку запроса, поскольку она уже является частью {REQUEST_URI} (в противном случае параметры добавляются дважды). <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
Франзо
6
Это работает, но, к сожалению, также на localhost. Чтобы избежать этого, вы можете добавить это в <условие>: <add input = "{HTTP_HOST}" pattern = "localhost" negate = "true" />
wezzix
5
Используя AWS Elastic beanstalk, этот метод давал мне 302 Слишком много перенаправлений, пока я не изменил: <match url=".*"/>к<match url="http://*.*" />
Кевину Р.
1
@Sam Может быть, у вас не установлен модуль перезаписи URL? Он не поставляется с IIS по умолчанию, должен быть установлен отдельно. Например, docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
LazyOne
80

Для тех, кто использует ASP.NET MVC. Вы можете использовать RequireHttpsAttribute, чтобы все ответы были HTTPS:

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

Другие вещи, которые вы также можете сделать, чтобы защитить свой сайт:

  1. Принудительно использовать токены Anti-Forgery для использования SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. Требовать, чтобы Cookies требовали HTTPS по умолчанию, изменив файл Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
    
  3. Используйте пакет NWebSec.Owin NuGet и добавьте следующую строку кода для включения строгой транспортной безопасности (HSTS) на сайте. Не забудьте добавить директиву Preload ниже и отправить свой сайт на сайт HSTS Preload . Больше информации здесь и здесь . Обратите внимание, что если вы не используете OWIN, существует метод Web.config, о котором вы можете прочитать на сайте NWebSec .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
    
  4. Используйте пакет 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));
    
  5. Включите схему https в любой используемый URL. HTTP-заголовок Content Security Policy (CSP) и 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 .

Мухаммед Рехан Саид
источник
4
Этот вопрос требует ASP.NET, но не содержит WebForms или MVC, поэтому я дал исчерпывающий ответ для тех, кто использует MVC (который не использует файл Web.config для принудительной установки HTTPS) и все же ... проголосовал против.
Мухаммед Рехан Саид
6
а) Решение работает, но все изменилось, этот выдающийся вопрос с высоким рейтингом заслуживает обновленного ответа с использованием встроенного в MVC. б) Ответ пытается охватить все основы. Вопрос не простой, включение HTTPS для всего сайта требует гораздо большего, чем изменение файла web.config. Читатели могут быть введены в заблуждение, думая, что изменение файла Web.config - это все, что нужно. Безопасность достаточно сложна, как и без неполных / устаревших ответов.
Мухаммед Рехан Саид
11
На мой взгляд, это отличный и ценный ответ. Когда кто-то гуглит тему и направляется на этот вопрос, я рад, что ваш ответ здесь.
Президент Джеймс К. Полк
1
@MuhammadRehanSaeed Хороший пост. Может быть, добавить SRI в свой список? scotthelme.co.uk/subresource-integrity
Натан
1
@MuhammadRehanSaeed true - я думаю, что заголовок «Другие вещи, которые вы также можете захотеть сделать, чтобы защитить свой сайт», заставил меня задуматься об этом :)
Натан
14

Чтобы дополнить ответ 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 удаляет все серверные правила, которые мы могли бы наследовать.
  • Правило определяет правило.
    • Назовите произвольное (хотя и уникальное) имя для правила.
    • stopProcessing, следует ли направить запрос немедленно в конвейер запросов IIS или сначала обработать дополнительные правила.
  • соответствует, когда запустить это правило.
    • URL шаблон, по которому можно оценить URL
  • условия дополнительных условий о том, когда выполнять это правило; условия обрабатываются только при первом совпадении.
    • логическая группировка - все ли условия должны быть истинными ( MatchAll) или любое из условий должно быть истинным ( MatchAny); похож на И против ИЛИ.
  • add добавляет условие, которое должно быть выполнено.
    • введите входные данные, которые оценивает условие; входные данные могут быть переменными сервера.
    • шаблон стандарта, по которому оценивать ввод.
    • ignoreCase имеет значение капитализация или нет.
  • действие, что делать, если matchи conditionsвсе это правда.
    • Тип обычно может быть redirect(на стороне клиента) или rewrite(на стороне сервера).
    • URL, что производить в результате этого правила; в этом случае объедините https://с двумя переменными сервера.
    • redirectType какой HTTP редирект использовать; это постоянный 301
    • appendQueryString , добавлять ли строку запроса в конце результирующего urlили нет; в этом случае мы устанавливаем значение false, потому что оно {REQUEST_URI}уже включено.

Переменные сервера

  • {HTTPS}который либо OFFили ON.
  • {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

Шон Луттин
источник
1
Одно замечание: фрагмент URL (from /home?key=value#fragment) не установлен на сервере браузерами, так как он предназначен для локального использования.
LazyOne
@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 в https://www.example.com/members- браузер сделает все остальное)
LazyOne
@LazyOne Спасибо за это. Если я правильно помню, есть несколько ошибок WebKit, которые препятствуют включению фрагмента в перенаправления. Итак, это имеет смысл. bugs.webkit.org/show_bug.cgi?id=24175
Шон Луттин
1
en.wikipedia.org/wiki/Fragment_identifier - «Клиенты не должны отправлять URI-фрагменты на серверы при получении документа, а без помощи локального приложения (см. ниже) фрагменты не участвуют в перенаправлениях HTTP» - просто чтобы было ясно, если я неправильно понял ваш последний комментарий.
LazyOne
6

Принятый ответ не работал для меня. Я следовал за шагами в этом блоге .

Ключевым моментом, который мне не хватало, было то, что мне нужно было загрузить и установить инструмент перезаписи URL для IIS. Я нашел это здесь . Результат был следующий.

<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>
Эрик
источник
1

В .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);
Оракул
источник
0

Отличная библиотека NWebsec может обновить ваши запросы с HTTP на HTTPS, используя свой upgrade-insecure-requestsтег в Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>
Что он делает
источник
0

Мне не разрешили установить 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

Я создал HTML-файл, который выполняет перенаправление (redirectToHttps.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>

Я надеюсь, что кто-то найдет это полезным, так как я не смог найти все части в одном месте в другом месте.

Спенсер Салливан
источник
-7

Простой способ это сказать 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>
редирект
источник
Почему отрицательный голос? Работает и отвечает на вопрос.
перенаправить
14
Это голос против, потому что вы говорите Google, что ваш файл не найден, а затем вы используете JavaScript для перенаправления, что обычно просто плохо.
Томас Беннетт