Como forçar HTTPS usando um arquivo web.config

220

Eu pesquisei no Google e no StackOverflow tentando encontrar uma solução para isso, mas todos parecem estar relacionados ao ASP.NET etc.

Normalmente, executo o Linux nos meus servidores, mas para este cliente, estou usando o Windows com IIS 7.5 (e Plesk 10). Essa é a razão pela qual não estou familiarizado com os arquivos IIS e web.config . Em um .htaccessarquivo, você pode usar condições de reescrita para detectar se o protocolo é HTTPS e redirecionar de acordo. Existe uma maneira simples de conseguir isso usando um arquivo web.config ou mesmo usando o módulo ' URL Rewrite ' que eu instalei?

Como não tenho experiência com o ASP.NET , se isso estiver envolvido na solução, inclua etapas claras de como implementar.

O motivo para eu fazer isso com o web.config e não com o PHP é que eu gostaria de forçar o HTTPS em todos os ativos no site.

Ben Carey
fonte

Respostas:

427

Você precisa do módulo de reconfiguração de URL, preferencialmente v2 (não tenho v1 instalado, portanto, não posso garantir que ele funcione lá, mas deveria).

Aqui está um exemplo desse web.config - ele forçará o HTTPS para TODOS os recursos (usando o redirecionamento permanente 301):

<?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 Esta solução em particular não tem nada a ver com ASP.NET/PHP ou qualquer outra tecnologia, pois é feita usando apenas o módulo de reescrita de URL - é processada em um dos níveis inicial / inferior - antes que a solicitação chegue ao ponto em que seu código é executado.

LazyOne
fonte
6
@BenCarey Você também deve olhar para Strict-Transport-Securitycabeçalho: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne
22
Eu recomendo alterar o redirecionamento para que não acrescente a string de consulta, pois ela já faz parte de {REQUEST_URI} (caso contrário, os parâmetros serão adicionados duas vezes). <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
Franzo
6
Isso funciona, mas infelizmente também no localhost. Para evitar isso, você pode adicioná-lo a <conditions>: <add input = "{HTTP_HOST}" pattern = "localhost" negate = "true" />
wezzix 17/17/17
5
Usando o AWS Elastic beanstalk, esse método estava me dando redirecionamentos 302 em excesso até que eu modifiquei: <match url=".*"/>para<match url="http://*.*" />
Kevin R.
1
@ Sam Talvez você não tenha o módulo de reescrita de URL instalado? Ele não vem com o IIS por padrão, precisa ser instalado separadamente. Por exemplo, docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
LazyOne
80

Para aqueles que usam o ASP.NET MVC. Você pode usar o RequireHttpsAttribute para forçar todas as respostas a serem HTTPS:

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

Outras ações que você também pode querer fazer para ajudar a proteger seu site:

  1. Forçar tokens antifalsificação a usar SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. Exija que os cookies exijam HTTPS por padrão, alterando o arquivo Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
    
  3. Use o pacote NWebSec.Owin NuGet e adicione a seguinte linha de código para habilitar o HSTS (Strict Transport Security) em todo o site. Não se esqueça de adicionar a diretiva de pré-carregamento abaixo e enviar seu site para o site de pré-carregamento do HSTS . Mais informações aqui e aqui . Observe que, se você não estiver usando o OWIN, existe um método Web.config que você pode ler no site NWebSec .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
    
  4. Use o pacote NWebSec.Owin NuGet e adicione a seguinte linha de código para ativar a Public Key Pinning (HPKP) em todo o site. Mais informações aqui e aqui .

    // 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. Inclua o esquema https em qualquer URL usado. O cabeçalho HTTP da CSP (Content Security Policy) e o SRI (Subresource Integrity) não são bons quando você imita o esquema em alguns navegadores. É melhor ser explícito sobre HTTPS. por exemplo

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
    
  6. Use o modelo de projeto do ASP.NET MVC Boilerplate Visual Studio para gerar um projeto com tudo isso e muito mais incorporado. Você também pode exibir o código no GitHub .

Muhammad Rehan Saeed
fonte
4
A pergunta solicita o ASP.NET, mas não indica WebForms ou MVC, por isso dei uma resposta abrangente para aqueles que usam MVC (que não usa o arquivo Web.config para forçar HTTPS) e ainda assim ... diminuiu o voto.
Muhammad Rehan Saeed
6
a) A solução funciona, mas as coisas mudaram; essa pergunta proeminente e de alta classificação merece uma resposta atualizada usando o que está embutido no MVC. b) A resposta tenta cobrir todas as bases. A questão não é simples, habilitar o HTTPS em um site inteiro requer muito mais do que alterar um arquivo web.config. Os leitores podem ser enganados ao pensar que basta alterar um arquivo Web.config. A segurança é difícil o suficiente, sem respostas incompletas / desatualizadas.
Muhammad Rehan Saeed
11
Na minha opinião, esta é uma resposta excelente e valiosa. Quando alguém analisa o tópico e é direcionado a essa pergunta, fico feliz que sua resposta esteja aqui.
Presidente James K. Polk
1
@MuhammadRehanSaeed Nice post. Talvez adicione SRI à sua lista? scotthelme.co.uk/subresource-integrity
Nathan
1
@MuhammadRehanSaeed verdade - Eu acho que o título de "Outras coisas que você pode também querer fazer para ajudar a proteger o seu site" me fez pensar nisso :)
Nathan
14

Para aumentar a resposta do LazyOne, aqui está uma versão anotada da resposta.

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

Limpe todas as outras regras que já possam ter sido definidas neste servidor. Crie uma nova regra, denominada "Redirecionar todas as solicitações para https". Depois de processar esta regra, não processe mais nenhuma regra! Corresponda a todos os URLs recebidos. Em seguida, verifique se todas essas outras condições são verdadeiras: HTTPS está desativado. Bem, isso é apenas uma condição (mas verifique se é verdade). Se estiver, envie um redirecionamento 301 permanente de volta ao cliente em http://www.foobar.com/whatever?else=the#url-contains. Não adicione a string de consulta no final disso, porque duplicaria a string de consulta!

É isso que as propriedades, atributos e alguns dos valores significam.

  • clear remove todas as regras do servidor que poderíamos herdar.
  • regra define uma regra.
    • nomeie um nome arbitrário (embora único) para a regra.
    • stopProcessing: encaminhar a solicitação imediatamente para o pipeline de solicitações do IIS ou primeiro para processar regras adicionais.
  • corresponde a quando executar esta regra.
    • url de um padrão no qual avaliar a URL
  • condiciona condições adicionais sobre quando executar esta regra; as condições são processadas apenas se houver uma primeira correspondência.
    • logicGrouping se todas as condições devem ser verdadeiras ( MatchAll) ou se alguma delas deve ser verdadeira ( MatchAny); semelhante a AND vs OR.
  • add adiciona uma condição que deve ser atendida.
    • insira a entrada que uma condição está avaliando; entrada pode ser variável do servidor.
    • padrão do padrão contra o qual avaliar a entrada.
    • ignoreCase se a capitalização é importante ou não.
  • ação o que fazer se o matche sua conditionssão todas verdadeiras.
    • O tipo geralmente pode ser redirect(do lado do cliente) ou rewrite(do lado do servidor).
    • url o que produzir como resultado desta regra; nesse caso, concatene https://com duas variáveis ​​de servidor.
    • redirectType que redirecionamento HTTP usar; este é um permanente 301.
    • appendQueryString se deseja adicionar a sequência de consultas no final da resultante urlou não; neste caso, estamos definindo-o como false, porque o {REQUEST_URI}já o inclui.

As variáveis ​​do servidor são

  • {HTTPS}qual é OFFou ON.
  • {HTTP_HOST}é www.mysite.come
  • {REQUEST_URI} inclui o restante do URI, por exemplo /home?key=value
    • o navegador lida com #fragment(veja o comentário do LazyOne).

Consulte também: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference

Shaun Luttin
fonte
1
Uma observação: parte do fragmento da URL (de /home?key=value#fragment) não é definida pelo servidor pelos navegadores, pois deve ser usada localmente.
precisa saber é o seguinte
@LazyOne Question. Estamos usando o web.config acima para redirecionar de greenearth.game/about#foo para HTTPS. A mudança para HTTPS inclui o fragmento #foo. Como a parte #foo não é enviada ao servidor, como o redirecionamento a inclui?
Shaun Luttin
É tratado pelo navegador. Basta abrir a guia de rede no Google Chrome (ou similar no Firefox etc) e ver qual URL é realmente solicitado (por exemplo, o http://www.example.com/members#oopspedido será enviado para o http://www.example.com/membersqual será redirecionado para a versão HTTPS em https://www.example.com/members- o navegador faz o resto)
LazyOne
@LazyOne Obrigado por isso. Se bem me lembro, existem alguns bugs do WebKit que impedem que o fragmento seja incluído nos redirecionamentos. Então, isso faz sentido. bugs.webkit.org/show_bug.cgi?id=24175
Shaun Luttin
1
pt.wikipedia.org/wiki/Fragment_identifier - "Os clientes não devem enviar fragmentos de URI aos servidores quando recuperam um documento e sem a ajuda de um aplicativo local (veja abaixo) os fragmentos não participam de redirecionamentos HTTP" - só para ficar claro, caso eu tenha entendido mal o seu último comentário.
precisa saber é o seguinte
6

A resposta aceita não funcionou para mim. Eu segui as etapas deste blog .

Um ponto importante que estava faltando para mim era que eu precisava baixar e instalar a Ferramenta de Reescrita de URL para IIS. Encontrei aqui . O resultado foi o seguinte.

<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>
Eric
fonte
1

No .Net Core, siga as instruções em https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

No seu startup.cs, adicione o seguinte:

// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });`enter code here`

Para redirecionar Http para Https, adicione o seguinte no arquivo 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);
Homem Oracular
fonte
0

A excelente biblioteca NWebsec pode atualizar suas solicitações de HTTP para HTTPS usando sua upgrade-insecure-requeststag dentro de Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>
O que ele está fazendo
fonte
0

Como não havia permissão para instalar a reescrita de URL no meu ambiente, encontrei outro caminho.

Adicionando isso ao meu web.config, o erro foi reescrito e funcionou no 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>

Em seguida, seguindo os conselhos aqui: https://www.sslshopper.com/iis7-redirect-http-to-https.html

Eu criei o arquivo html que faz o redirecionamento (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>

Espero que alguém ache isso útil, pois não consegui encontrar todas as peças em um só lugar em qualquer outro lugar.

Spencer Sullivan
fonte
-7

Uma maneira simples é dizer ao IIS para enviar seu arquivo de erro personalizado para solicitações HTTP. O arquivo pode conter um meta-redirecionamento, um redirecionamento de JavaScript e instruções com o link, etc ... Importante: você ainda pode marcar "Requer SSL" para o site (ou pasta) e isso funcionará.

</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>
redirecionar
fonte
Por que o voto negativo? Funciona e responde à pergunta.
redirecionar
14
Este é um voto negativo, porque você está dizendo ao Google que seu arquivo não foi encontrado e depois está usando o JavaScript para redirecionar, o que normalmente é ruim.
Thomas Bennett