Pregunta

Hace unos 6 meses lancé un sitio donde cada solicitud debía realizarse a través de https.La única manera que pude encontrar en ese momento para asegurarme de que cada solicitud a una página fuera a través de https era verificarla en el evento de carga de la página.Si la solicitud no fuera a través de http, respondería.redirect("https://ejemplo.com")

¿Existe una manera mejor, idealmente alguna configuración en web.config?

¿Fue útil?

Solución

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

Respuesta original (reemplazado por el anterior el 4 de diciembre de 2015)

básicamente

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

eso iría en global.asax.cs (o global.asax.vb)

No conozco una manera de especificarlo en web.config

Otros consejos

La otra cosa que puedes hacer es usar HSTS devolviendo el encabezado "Strict-Transport-Security" al navegador.El navegador tiene que admitir esto (y en la actualidad, son principalmente Chrome y Firefox los que lo hacen), pero significa que una vez configurado, el navegador no realizará solicitudes al sitio a través de HTTP y, en cambio, las traducirá a solicitudes HTTPS antes de emitirlas. .Pruebe esto en combinación con una redirección desde 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;
  }
}

Los navegadores que no son compatibles con HSTS simplemente ignorarán el encabezado, pero aún así serán atrapados por la declaración de cambio y enviados a HTTPS.

El módulo IIS7 te permitirá redirigir.

    <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 aquellos que usan ASP.NET MVC.Puede utilizar lo siguiente para forzar SSL/TLS sobre HTTPS en todo el sitio de dos maneras:

El camino difícil

1 - Agregue RequireHttpsAttribute a los filtros globales:

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

2 - Forzar que los tokens Anti-Falsificación utilicen SSL/TLS:

AntiForgeryConfig.RequireSsl = true;

3 - Requerir cookies para requerir HTTPS de forma predeterminada cambiando el archivo Web.config:

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

4: utilice el paquete NWebSec.Owin NuGet y agregue la siguiente línea de código para habilitar la seguridad de transporte estricta en todo el sitio.No olvide agregar la directiva Preload a continuación y enviar su sitio al Sitio de precarga HSTS.Más información aquí y aquí.Tenga en cuenta que si no está utilizando OWIN, existe un método Web.config que puede leer en el NWebSec sitio.

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

5 - Utilice el paquete NWebSec.Owin NuGet y agregue la siguiente línea de código para habilitar la fijación de clave pública (HPKP) en todo el sitio.Más información aquí y aquí.

// 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 - Incluye el esquema https en cualquier URL utilizada. Política de seguridad de contenido (CSP) encabezado HTTP y Integridad de los subrecursos (SRI) No seas amable cuando imites el esquema en algunos navegadores.Es mejor ser explícito sobre HTTPS.p.ej.

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>

La manera fácil

Utilizar el Modelo estándar de ASP.NET MVC Plantilla de proyecto de Visual Studio para generar un proyecto con todo esto y mucho más integrado.También puedes ver el código en GitHub.

Si no puede configurar esto en IIS por cualquier motivo, crearía un módulo HTTP que realice la redirección por usted:

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

Luego simplemente compílelo en una DLL, agréguelo como referencia a su proyecto y colóquelo en web.config:

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

Lo que debes hacer es:

1) Agregue una clave dentro de web.config, según el servidor de producción o etapa, como se muestra a continuación

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

2) Dentro de su archivo Global.asax agregue el siguiente método.

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

Si la compatibilidad con SSL no se puede configurar en su sitio (es decir,debería poder activar/desactivar https): puede utilizar el atributo [RequireHttps] en cualquier controlador/acción del controlador que desee proteger.

También depende de la marca de su balanceador; para web mux, deberá buscar el encabezado http X-WebMux-SSL-termination: true para calcular que el tráfico entrante era SSL.detalles aquí: http://www.cainetworks.com/support/redirect2ssl.html

Para @Joe arriba, "Esto me está dando un bucle de redireccionamiento.Antes de agregar el código, funcionaba bien.¿Alguna sugerencia?– Joe el 8 de noviembre, 2011 a las 4:13"

Esto también me estaba sucediendo a mí y lo que creo que estaba sucediendo es que había un equilibrador de carga que finalizaba la solicitud SSL frente al servidor web.Entonces, mi sitio web siempre pensaba que la solicitud era "http", incluso si el navegador original solicitaba que fuera "https".

Admito que esto es un poco complicado, pero lo que funcionó para mí fue implementar una propiedad "JustRedirected" que pude aprovechar para descubrir que la persona ya fue redirigida una vez.Entonces, pruebo condiciones específicas que justifican la redirección y, si se cumplen, configuro esta propiedad (valor almacenado en la sesión) antes de la redirección.Incluso si las condiciones http/https para la redirección se cumplen la segunda vez, evito la lógica de redirección y restablezco el valor de la sesión "JustRedirected" a falso.Necesitará su propia lógica de prueba condicional, pero aquí hay una implementación simple de la propiedad:

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

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

Voy a aportar mi granito de arena. SI Si tiene acceso al lado del servidor IIS, puede forzar HTTPS mediante el uso de enlaces de protocolo.Por ejemplo, tienes un sitio web llamado Paja.En IIS configurarías dos sitios: Paja, y Bla (Redireccionar).Para Paja configurar solo el HTTPS vinculante (y FTP si es necesario, asegúrese de forzarlo también a través de una conexión segura).Para Bla (Redireccionar) configurar solo el HTTP vinculante.Por último, en el Redirección HTTP sección para Bla (Redireccionar) asegúrese de configurar una redirección 301 a https://blah.com, con destino exacto habilitado.Asegúrese de que cada sitio en IIS apunte a su propio carpeta raíz, de lo contrario, Web.config se arruinará todo.También asegúrese de tener HSTS configurado en su sitio HTTPSed para que las solicitudes posteriores del navegador siempre sean forzadas a HTTPS y no se produzcan redirecciones.

Esta es una respuesta más completa basada en la de @Troy Hunt.Añade esta función a tu WebApplication clase en 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 en su compilación local, habilítelo en el panel de Propiedades del proyecto)

-> Simplemente AGREGUE [RequireHttps] encima de la clase pública HomeController:Controlador.

-> Y agregue GlobalFilters.Filters.Add(new RequireHttpsAttribute());en el método 'protegido void Application_Start()' en el archivo Global.asax.cs.

Lo que obliga a toda su aplicación a HTTPS.

Pasé algún tiempo buscando mejores prácticas que tuvieran sentido y encontré lo siguiente que funcionó perfecto para mí.Espero que esto te salve algún día.

Usando Archivo de configuración (por ejemplo, un sitio web asp.net)https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/

o en tu propio servidorhttps://www.sslshopper.com/iis7-redirect-http-to-https.html

Respuesta corta] Simplemente el siguiente código 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>

Si está utilizando ASP.NET Core, puede probar el paquete nuget SaidOut.AspNetCore.HttpsWithStrictTransportSecurity.

Entonces solo necesitas agregar

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

Esto también agregará el encabezado HTTP StrictTransportSecurity a todas las solicitudes realizadas mediante el esquema https.

Código de ejemplo y documentación. https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code

En IIS10 (Windows 10 y Server 2016), desde la versión 1709 en adelante, existe una opción nueva y más sencilla para habilitar HSTS para un sitio web.

Microsoft describe las ventajas del nuevo enfoque aquí, y proporciona muchos ejemplos diferentes de cómo implementar el cambio mediante programación o editando directamente el archivo ApplicationHost.config (que es como web.config pero opera a nivel de IIS, en lugar de a nivel de sitio individual).ApplicationHost.config se puede encontrar en C:\Windows\System32\inetsrv\config.

Aquí describí dos de los métodos de ejemplo para evitar la descomposición del enlace.

Método 1 - Edite el archivo ApplicationHost.Config directamente entre el <site> etiquetas, agregue esta línea:

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

Método 2 - Línea de comando:Ejecute lo siguiente desde un símbolo del sistema elevado (es decir,botón derecho del mouse en CMD y ejecutar como administrador).Recuerde cambiar Contoso por el nombre de su sitio tal como aparece en el Administrador de 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

Los otros métodos que ofrece Microsoft en esos artículos podrían ser mejores opciones si se encuentra en un entorno alojado donde tiene acceso limitado.

Tenga en cuenta que la versión 1709 de IIS10 ya está disponible en Windows 10, pero para Windows Server 2016 se encuentra en una vía de lanzamiento diferente y no se lanzará como parche o paquete de servicio.Ver aquí para obtener detalles sobre 1709.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top