Pergunta

Há cerca de 6 meses, lancei um site onde todas as solicitações precisavam ser feitas por meio de https.A única maneira que encontrei no momento de garantir que todas as solicitações para uma página fossem feitas por meio de https foi verificá-las no evento de carregamento da página.Se a solicitação não fosse por http eu responderia.redirect("https://example.com")

Existe uma maneira melhor - de preferência alguma configuração no web.config?

Foi útil?

Solução

Por favor use HSTS

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

Resposta original (substituído pelo acima em 4 de dezembro de 2015)

basicamente

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

isso iria para global.asax.cs (ou global.asax.vb)

não sei como especificá-lo no web.config

Outras dicas

A outra coisa que você pode fazer é usar HSTS retornando o cabeçalho "Strict-Transport-Security" ao navegador.O navegador deve suportar isso (e no momento, são principalmente o Chrome e o Firefox que o fazem), mas isso significa que, uma vez definido, o navegador não fará solicitações ao site por HTTP e, em vez disso, as traduzirá em solicitações HTTPS antes de emiti-las. .Tente isto em combinação com um redirecionamento de 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;
  }
}

Os navegadores que não reconhecem o HSTS simplesmente ignorarão o cabeçalho, mas ainda assim serão capturados pela instrução switch e enviados para HTTPS.

O módulo IIS7 permitirá redirecionar.

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

Para quem usa ASP.NET MVC.Você pode usar o seguinte para forçar SSL/TLS sobre HTTPS em todo o site de duas maneiras:

O jeito difícil

1 - Adicione o RequireHttpsAttribute aos filtros globais:

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

2 - Forçar tokens antifalsificação a usar SSL/TLS:

AntiForgeryConfig.RequireSsl = true;

3 - Exigir que os Cookies exijam HTTPS por padrão alterando o arquivo Web.config:

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

4 - Use o pacote NWebSec.Owin NuGet e adicione a seguinte linha de código para habilitar Strict Transport Security em todo o site.Não se esqueça de adicionar a diretiva Preload abaixo e enviar seu site para o Site de pré-carregamento 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 NWebSec site.

// app is your OWIN IAppBuilder app in Startup.cs
app.UseHsts(options => options.MaxAge(days: 30).Preload());

5 - Use o pacote NWebSec.Owin NuGet e adicione a seguinte linha de código para habilitar a fixação de chave pública (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));

6 - Incluir o esquema https em qualquer URL's utilizada. Política de segurança de conteúdo (CSP) Cabeçalho HTTP e Integridade de sub-recursos (SRI) não seja gentil ao imitar 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>

O caminho fácil

Use o Padrão ASP.NET MVC Modelo de projeto do Visual Studio para gerar um projeto com tudo isso e muito mais integrado.Você também pode visualizar o código em GitHub.

Se você não conseguir configurar isso no IIS por qualquer motivo, eu criaria um módulo HTTP que redirecionaria para você:

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

Depois é só compilá-lo em uma DLL, adicioná-lo como referência ao seu projeto e colocar isto no web.config:

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

O que você precisa fazer é:

1) Adicione uma chave dentro do web.config, dependendo do servidor de produção ou de estágio, como abaixo

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

2) Dentro do seu arquivo Global.asax, adicione o método abaixo.

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

Se o suporte SSL não for configurável em seu site (ou seja,deve ser capaz de ativar/desativar o https) - você pode usar o atributo [RequireHttps] em qualquer controlador/ação do controlador que deseja proteger.

Depende também da marca do seu balanceador, para o web mux você precisaria procurar o cabeçalho http X-WebMux-SSL-termination: true para descobrir que o tráfego de entrada era SSL.detalhes aqui: http://www.cainetworks.com/support/redirect2ssl.html

Para @Joe acima, "Isso está me proporcionando um loop de redirecionamento.Antes de adicionar o código, funcionou bem.Alguma sugestão?– Joe 8 de novembro de 2011 às 4:13"

Isso também estava acontecendo comigo e o que acredito que estava acontecendo é que havia um balanceador de carga encerrando a solicitação SSL na frente do servidor Web.Portanto, meu site sempre pensava que a solicitação era "http", mesmo que o navegador original solicitasse que fosse "https".

Admito que isso é um pouco hackeado, mas o que funcionou para mim foi implementar uma propriedade "JustRedirected" que eu pudesse aproveitar para descobrir que a pessoa já foi redirecionada uma vez.Portanto, testo as condições específicas que justificam o redirecionamento e, caso sejam atendidas, defino essa propriedade (valor armazenado na sessão) antes do redirecionamento.Mesmo que as condições http/https para redirecionamento sejam atendidas pela segunda vez, eu ignoro a lógica de redirecionamento e redefino o valor da sessão "JustRedirected" para falso.Você precisará de sua própria lógica de teste condicional, mas aqui está uma implementação simples da propriedade:

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

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

Vou apostar meus dois centavos. SE você tem acesso ao lado do servidor IIS, então você pode forçar o HTTPS usando as ligações do protocolo.Por exemplo, você tem um site chamado Blá.No IIS você configuraria dois sites: Blá, e Blá (redirecionar).Para Blá configure apenas o HTTPS vinculativo (e FTP se necessário, certifique-se de forçá-lo também em uma conexão segura).Para Blá (redirecionar) configure apenas o HTTP vinculativo.Por último, no Redirecionamento HTTP seção para Blá (redirecionar) certifique-se de definir um redirecionamento 301 para https://blah.com, com o destino exato ativado.Certifique-se de que cada site no IIS esteja apontando para seu ter pasta raiz, caso contrário o Web.config vai ficar tudo bagunçado.Certifique-se também de ter HSTS configurado em seu site HTTPSed para que as solicitações subsequentes do navegador sejam sempre forçadas para HTTPS e nenhum redirecionamento ocorra.

Esta é uma resposta mais completa baseada na de @Troy Hunt.Adicione esta função ao seu WebApplication aula em 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;
            }
        }
    }

(Para habilitar SSL em sua compilação local, habilite-o na doca Propriedades do projeto)

-> Simplesmente ADICIONE [RequireHttps] no topo da classe pública HomeController:Controlador.

-> E adicione GlobalFilters.Filters.Add(new RequireHttpsAttribute());no método 'protected void Application_Start ()' no arquivo Global.asax.cs.

O que força todo o seu aplicativo para HTTPS.

Passei algum tempo procurando as melhores práticas que fizessem sentido e descobri as seguintes que funcionaram perfeitamente para mim.Espero que isso o salve algum dia.

Usando Arquivo de configuração (por exemplo, um site asp.net)https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/

ou em seu próprio servidorhttps://www.sslshopper.com/iis7-redirect-http-to-https.html

Resposta curta] Simplesmente o código abaixo entra

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

Se você estiver usando o ASP.NET Core, poderá experimentar o pacote nuget SaidOut.AspNetCore.HttpsWithStrictTransportSecurity.

Então você só precisa adicionar

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

Isso também adicionará o cabeçalho HTTP StrictTransportSecurity a todas as solicitações feitas usando o esquema https.

Exemplo de código e documentação https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code

No IIS10 (Windows 10 e Server 2016), a partir da versão 1709, existe uma opção nova e mais simples para habilitar HSTS para um site.

Microsoft descreve as vantagens da nova abordagem aqui, e fornece muitos exemplos diferentes de como implementar a alteração programaticamente ou editando diretamente o arquivo ApplicationHost.config (que é como web.config, mas opera no nível do IIS, em vez de no nível do site individual).ApplicationHost.config pode ser encontrado em C:\Windows\System32\inetsrv\config.

Descrevi dois dos métodos de exemplo aqui para evitar o apodrecimento do link.

Método 1 - Edite o arquivo ApplicationHost.Config diretamente entre o <site> tags, adicione esta linha:

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

Método 2 - Linha de comando:Execute o seguinte em um prompt de comando elevado (ou seja,mouse direito no CMD e execute como administrador).Lembre-se de trocar Contoso pelo nome do seu site conforme aparece no Gerenciador do 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

Os outros métodos que a Microsoft oferece nesses artigos podem ser opções melhores se você estiver em um ambiente hospedado com acesso limitado.

Tenha em mente que a versão 1709 do IIS10 está disponível no Windows 10 agora, mas para o Windows Server 2016 ele está em uma faixa de lançamento diferente e não será lançado como um patch ou service pack.Ver aqui para obter detalhes sobre 1709.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top