Melhor maneira de asp.net forçar https para um site inteiro?

Cerca de seis meses atrás, implementei um site em que todas as solicitações precisavam estar acima de https. A única maneira que eu encontrei para garantir que todas as solicitações para uma página fossem sobre https era verificar isso no evento de carregamento da página. Se a solicitação não tiver sido sobre http, eu responder.redirect (” https://example.com “)

Existe uma maneira melhor – idealmente alguma configuração no web.config?

    Por favor use HSTS

    de http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx

    < ?xml version="1.0" encoding="UTF-8"?>                         

    Resposta original (substituída pela 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); } } 

    que iria no global.asax.cs (ou global.asax.vb)

    Eu não sei de uma maneira de especificá-lo no web.config

    A outra coisa que você pode fazer é usar o HSTS , retornando o header “Strict-Transport-Security” para o navegador. O navegador tem que suportar isso (e atualmente, é principalmente Chrome e Firefox), mas isso significa que, uma vez configurado, o navegador não fará solicitações ao site via HTTP e as converterá em solicitações HTTPS antes de emiti-las . Tente isso em combinação com um redirecionamento do 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 são compatíveis com HSTS irão apenas ignorar o header, mas ainda serão pegos pela instrução switch e enviados para HTTPS.

    O módulo IIS7 permitirá que você redirecione.

                 

    Para aqueles que usam o ASP.NET MVC. Você pode usar o seguinte para forçar o 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 anti-falsificação para usar SSL / TLS:

     AntiForgeryConfig.RequireSsl = true; 

    3 – Exigir que os cookies exijam HTTPS por padrão, alterando o arquivo Web.config:

        

    4 – Use o pacote NWebSec.Owin NuGet e adicione a seguinte linha de código para habilitar a Segurança de Transporte Restrita 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 da HSTS . Mais informações aqui e aqui . Observe que, se você não estiver usando o OWIN, existe um método Web.config que pode ser lido no site do NWebSec .

     // 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 linha de código a seguir para ativar o HPNP (Public Key Pinning) 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 eg cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=", "Base64 encoded SHA-256 hash of your second backup certificate eg M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=") .MaxAge(days: 30)); 

    6 – Inclua o esquema https em qualquer URL usada. O header HTTP da Diretiva de segurança de conteúdo (CSP) e a integridade da sub – fonte (SRI) não são reproduzidos quando você o imita em alguns navegadores. É melhor ser explícito sobre HTTPS. por exemplo

      

    O caminho fácil

    Use o modelo de projeto ASP.NET MVC Boilerplate Visual Studio para gerar um projeto com tudo isso e muito mais incorporado. Você também pode visualizar o código no GitHub .

    Se você não conseguir configurar isso no IIS por alguma razão, eu faria um módulo HTTP que faz o redirecionamento para você:

     using System; using System.Web; namespace HttpsOnly { ///  /// Redirects the Request to HTTPS if it comes in on an insecure channel. ///  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 } } } 

    Em seguida, basta compilá-lo para uma DLL, adicioná-lo como uma referência ao seu projeto e colocar isso no web.config:

         

    O que você precisa fazer é:

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

      or  

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

    Também depende da marca do seu balanceador, para o web mux, você precisaria procurar pelo header http X-WebMux-SSL-termination: true para descobrir que o tráfego de input era ssl. detalhes aqui: http://www.cainetworks.com/support/redirect2ssl.html

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

    Vou jogar meus dois centavos dentro Se você tiver access ao lado do servidor IIS, então você pode forçar HTTPS pelo uso das ligações de protocolo. Por exemplo, você tem um site chamado Blah . No IIS você configuraria dois sites: Blah e Blah (Redirect) . Para o Blah, configure somente a binding HTTPS (e o FTP se necessário, certifique-se de forçá-lo por uma conexão segura também). Para Blah (Redirect), configure apenas a binding HTTP . Por fim, na seção HTTP Redirect para Blah (Redirect), defina um redirecionamento 301 para https://blah.com , com o destino exato ativado. Certifique-se de que cada site no IIS esteja apontando para sua própria pasta raiz, caso contrário, o Web.config ficará todo corrompido. Além disso, certifique-se de ter o HSTS configurado em seu site HTTPS para que as solicitações subsequentes do navegador sejam sempre forçadas para HTTPS e não ocorram redirecionamentos.

    Esta é uma resposta mais completa baseada no @Troy Hunt’s. Adicione esta function à sua class WebApplication 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 ativar o SSL em sua compilation local, ative-o na doca Propriedades do projeto)

    Para @Joe acima, “Isso está me dando um loop de redirecionamento. Antes de adicionar o código funcionou bem. Alguma sugestão? – Joe Nov 8 ’11 at 4:13”

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

    Eu admito que isso é um pouco hacky, mas o que funcionou para mim foi implementar uma propriedade “JustRedirected” que eu poderia aproveitar para descobrir que a pessoa já foi redirecionada uma vez. Então, eu testo para condições específicas que garantem o redirecionamento e, se elas forem atendidas, defino essa propriedade (valor armazenado na session) antes do redirecionamento. Mesmo se as condições de redirecionamento http / https forem atendidas na segunda vez, eu ignoro a lógica de redirecionamento e restaure o valor da session “JustRedirected” para false. Você precisará da 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; } } 

    -> Simplesmente adicione [RequireHttps] no topo da class pública HomeController: Controller.

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

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

    Então você só precisa adicionar

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

    Isso também adicionará o header 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

    Outra vantagem em se fazer o módulo http é, se você apenas o fornecer em global.asax.cs, ele apenas verifica SSL no Application_BeginRequest, o que significa que seu aplicativo não está totalmente protegido; ele só roteará para a versão SSL na primeira tentativa, e então o usuário poderá recortar e colar o URL de nenhum SSL e ignorá-lo.