Cómo forzar HTTPS usando un archivo web.config

220

He buscado en Google y StackOverflow tratando de encontrar una solución a esto, pero todos parecen estar relacionados con ASP.NET, etc.

Normalmente ejecuto Linux en mis servidores, pero para este cliente estoy usando Windows con IIS 7.5 (y Plesk 10). Esta es la razón por la que no estoy familiarizado con los archivos IIS y web.config . En un .htaccessarchivo puede usar condiciones de reescritura para detectar si el protocolo es HTTPS y redirigir en consecuencia. ¿Hay una manera simple de lograr esto usando un archivo web.config, o incluso usando el módulo ' URL Rewrite ' que he instalado?

No tengo experiencia con ASP.NET, así que si esto está involucrado en la solución, incluya pasos claros sobre cómo implementarlo.

La razón por la que hago esto con web.config y no PHP es que me gustaría forzar HTTPS en todos los activos dentro del sitio.

Ben Carey
fuente
1
Y lo contrario
Chris Moschini

Respuestas:

427

Necesita el módulo URL Rewrite, preferiblemente v2 (no tengo v1 instalado, así que no puedo garantizar que funcione allí, pero debería).

Aquí hay un ejemplo de tal web.config: forzará HTTPS para TODOS los recursos (usando 301 redireccionamiento permanente):

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

PD: Esta solución en particular no tiene nada que ver con ASP.NET/PHP o cualquier otra tecnología, ya que se hace utilizando solo el módulo de reescritura de URL, se procesa en uno de los niveles iniciales / inferiores, antes de que la solicitud llegue al punto donde su código se ejecuta

LazyOne
fuente
66
@BenCarey También debe mirar el Strict-Transport-Securityencabezado: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne
22
Recomiendo cambiar la redirección para que no agregue la cadena de consulta, ya que ya forma parte de {REQUEST_URI} (de lo contrario, los parámetros se agregan dos veces). <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
franzo
66
Esto funciona, pero desafortunadamente también en localhost. Para evitar esto, puede agregar esto a <condiciones>: <add input = "{HTTP_HOST}" pattern = "localhost" negate = "true" />
wezzix
55
Usando AWS Elastic beanstalk, este método me estaba dando 302 Demasiados redireccionamientos hasta que modifiqué: <match url=".*"/>a<match url="http://*.*" />
Kevin R.
1
@Sam ¿Quizás no tiene instalado el módulo URL Rewrite? No viene con IIS de manera predeterminada, debe instalarse por separado. Por ejemplo, docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
LazyOne
80

Para aquellos que usan ASP.NET MVC. Puede usar RequireHttpsAttribute para forzar que todas las respuestas sean HTTPS:

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

Otras cosas que también puede hacer para ayudar a proteger su sitio:

  1. Forzar tokens antifalsificación para usar SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. Requerir que las cookies requieran HTTPS de forma predeterminada cambiando el archivo Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
  3. Use el paquete NWebSec.Owin NuGet y agregue la siguiente línea de código para habilitar Strict Transport Security (HSTS) en todo el sitio. No olvide agregar la directiva de precarga a continuación y enviar su sitio al sitio de precarga de HSTS . Más información aquí y aquí . Tenga en cuenta que si no está utilizando OWIN, hay un método Web.config que puede leer en el sitio NWebSec .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
  4. Use 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));
  5. Incluya el esquema https en cualquier URL utilizada. El encabezado HTTP de la Política de seguridad de contenido (CSP) y la Integridad de recursos secundarios (SRI) no funcionan bien cuando se imita 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>
  6. Use la plantilla de proyecto ASP.NET MVC Boilerplate Visual Studio para generar un proyecto con todo esto y mucho más integrado. También puede ver el código en GitHub .

Muhammad Rehan Saeed
fuente
44
La pregunta pide ASP.NET pero no indica WebForms o MVC, por lo que di una respuesta integral para aquellos que usan MVC (que no usa el archivo Web.config para forzar HTTPS) y aún así ... rechazado.
Muhammad Rehan Saeed
66
a) La solución funciona pero las cosas han cambiado, esta pregunta prominente y de alta calificación merece una respuesta actualizada usando lo que está integrado en MVC. b) La respuesta intenta cubrir todas las bases. La pregunta no es simple, habilitar HTTPS en todo un sitio requiere mucho más que cambiar un archivo web.config. Los lectores pueden ser engañados para pensar que cambiar un archivo Web.config es todo lo que se necesita. La seguridad es lo suficientemente difícil como es sin respuestas incompletas / obsoletas.
Muhammad Rehan Saeed
11
En mi opinión, esta es una respuesta excelente y valiosa. Cuando alguien busca en Google el tema y se dirige a esta pregunta, me alegra que su respuesta esté aquí.
Presidente James K. Polk
1
@MuhammadRehanSaeed Buena publicación. ¿Quizás agregar SRI a tu lista? scotthelme.co.uk/subresource-integrity
Nathan
1
@MuhammadRehanSaeed cierto: supongo que tu título de "Otras cosas que quizás también quieras hacer para ayudar a asegurar tu sitio" me hizo pensar en ello :)
Nathan
14

Para aumentar la respuesta de LazyOne, aquí hay una versión anotada de la respuesta.

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

Borre todas las demás reglas que ya se hayan definido en este servidor. Cree una nueva regla, que llamaremos "Redirigir todas las solicitudes a https". Después de procesar esta regla, ¡no procese más reglas! Coincide con todas las URL entrantes. Luego verifique si todas estas otras condiciones son verdaderas: HTTPS está APAGADO. Bueno, esa es solo una condición (pero asegúrese de que sea verdad). Si es así, envíe una redirección 301 permanente al cliente en http://www.foobar.com/whatever?else=the#url-contains. ¡No agregue la cadena de consulta al final de eso, porque duplicaría la cadena de consulta!

Esto es lo que significan las propiedades, los atributos y algunos de los valores.

  • clear elimina todas las reglas del servidor que de otro modo podríamos heredar.
  • la regla define una regla.
    • nombra un nombre arbitrario (aunque único) para la regla.
    • stopProcessing para reenviar la solicitud inmediatamente a la canalización de solicitudes de IIS o primero para procesar reglas adicionales.
  • coincidir con cuándo ejecutar esta regla.
    • url un patrón contra el cual evaluar la URL
  • condiciones condiciones adicionales sobre cuándo ejecutar esta regla; las condiciones se procesan solo si primero hay una coincidencia.
    • logicalGrouping si todas las condiciones deben ser verdaderas ( MatchAll) o si alguna de las condiciones debe ser verdadera ( MatchAny); similar a AND vs OR.
  • add agrega una condición que debe cumplirse.
    • ingrese la entrada que una condición está evaluando; la entrada puede ser variables del servidor.
    • modelar el estándar contra el cual evaluar la entrada.
    • ignoreCase si la capitalización importa o no.
  • acción qué hacer si el matchy su conditionsson todos verdaderos.
    • El tipo generalmente puede ser redirect(del lado del cliente) o rewrite(del lado del servidor).
    • url qué producir como resultado de esta regla; en este caso, concatene https://con dos variables de servidor.
    • redirect Escriba qué redirección HTTP utilizar; Este es un 301 permanente.
    • appendQueryString si se agrega o no la cadena de consulta al final de la resultante url; en este caso, lo estamos configurando como falso, porque {REQUEST_URI}ya lo incluye.

Las variables del servidor son

  • {HTTPS}que es ya sea OFFo ON.
  • {HTTP_HOST}es www.mysite.comy
  • {REQUEST_URI} incluye el resto del URI, p. ej. /home?key=value
    • el navegador maneja el #fragment(ver comentario de LazyOne).

Ver también: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference

Shaun Luttin
fuente
1
Sin embargo, una nota: parte del fragmento de URL (desde /home?key=value#fragment) no está configurado en el servidor por los navegadores, ya que está destinado a ser utilizado localmente.
LazyOne
@LazyOne Question. Estamos utilizando el web.config anterior con éxito para redirigir desde greenearth.game/about#foo a HTTPS. El cambio a HTTPS incluye el fragmento #foo. Dado que la parte #foo no se envía al servidor, ¿cómo la incluye la redirección?
Shaun Luttin
Es manejado por el navegador. Simplemente abra la pestaña de red en Google Chrome (o similar en Firefox, etc.) y vea qué URL se solicita realmente (por ejemplo http://www.example.com/members#oops, se enviará la solicitud a la http://www.example.com/membersque luego se redirige a la versión HTTPS en https://www.example.com/members- el navegador hace el resto)
LazyOne
@LazyOne Gracias por eso. Si recuerdo correctamente, hay algunos errores de WebKit que evitan que el fragmento se incluya en los redireccionamientos. Entonces, esto tiene sentido. bugs.webkit.org/show_bug.cgi?id=24175
Shaun Luttin
1
en.wikipedia.org/wiki/Fragment_identifier - "Se supone que los clientes no deben enviar fragmentos de URI a los servidores cuando recuperan un documento, y sin la ayuda de una aplicación local (ver más abajo) los fragmentos no participan en las redirecciones HTTP" - para que quede claro en caso de que haya entendido mal su último comentario.
LazyOne
6

La respuesta aceptada no funcionó para mí. Seguí los pasos en este blog .

Un punto clave que me faltaba era que necesitaba descargar e instalar la herramienta de reescritura de URL para IIS. Lo encontré aquí . El resultado fue el siguiente.

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

En .Net Core, siga las instrucciones en https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

En su startup.cs agregue lo siguiente:

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

Para redirigir Http a Https, agregue lo siguiente en 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);
Hombre oracular
fuente
0

La excelente biblioteca NWebsec puede actualizar sus solicitudes de HTTP a HTTPS utilizando su upgrade-insecure-requestsetiqueta dentro de Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>
Qué está haciendo
fuente
0

No se me permitió instalar URL Rewrite en mi entorno, así que encontré otra ruta.

Al agregar esto a mi web.config, se agregó el error de reescritura y funcionó en 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>

Luego, siguiendo los consejos aquí: https://www.sslshopper.com/iis7-redirect-http-to-https.html

Creé el archivo html que hace la redirección (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 alguien encuentre esto útil ya que no pude encontrar todas las piezas en un lugar en ningún otro lugar.

Spencer Sullivan
fuente
-7

Una manera simple es decirle a IIS que envíe su archivo de error personalizado para solicitudes HTTP. El archivo puede contener un meta redireccionamiento, un redireccionamiento de JavaScript e instrucciones con un enlace, etc. Es importante destacar que aún puede marcar "Requerir SSL" para el sitio (o carpeta) y esto 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>
redirigir
fuente
¿Por qué es el voto negativo? Funciona y responde la pregunta.
redirigir
14
Este es un voto negativo porque le está diciendo a Google que no se encuentra su archivo y luego está usando JavaScript para redirigir, lo que generalmente es malo.
Thomas Bennett