2010-04-09 19 views
21

Estoy trabajando en un sitio web que utiliza la función de reescritura de URL de IIS 7 para hacer un redireccionamiento permanente de example.com a www.example.com, así como también reescrituras de nombres de dominio similares al "principal", como por ejemplo desde www.examples.com a www.example.com.Reescritura de URL de IIS7: ¿Cómo no eliminar el protocolo HTTPS de la URL reescrita?

Esta regla de reescritura, que se muestra a continuación, ha funcionado bien desde hace un tiempo. Sin embargo, recientemente agregamos compatibilidad con HTTPS y notamos que si los usuarios visitan una de las URL que se reescribirán en www.example.com, se eliminará HTTPS. Por ejemplo, si un usuario visita https://example.com, se le redirige a http://www.example.com, mientras que nos gustaría que se envíe a https://www.example.com.

Esta es la regla de reescritura de interés (en Web.config):

<rule name="Canonical Host Name" stopProcessing="true"> 
    <match url="(.*)" /> 

    <conditions logicalGrouping="MatchAny"> 
     <add input="{HTTP_HOST}" pattern="^example\.com$" /> 
     <add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" /> 
     <add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" /> 
     <add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" /> 
    </conditions> 

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" /> 
</rule> 

Como se puede ver, la URL del elemento de acción atributo apunta directamente a la dirección http: //, por lo que entiendo por qué se redirige https://example.com a http://www.example.com. Mi pregunta es, ¿cómo soluciono esto? Intenté (ingenuamente) simplemente colocar la parte http: // del atributo url, pero eso no funcionó.

+0

Parece ser que simplemente dejando 'http: //' fuera de la URL de redireccionamiento hará que IIS 7.5 para usar el protocolo de la solicitud entrante. – HABO

Respuesta

10

Encontré la respuesta con la ayuda de mis colegas.

Necesitaba usar varias reglas con una condición en {HTTPS}. Tenga en cuenta la condición {HTTPS} en las reglas a continuación.

<rule name="Canonical Host Name (HTTP)" stopProcessing="true"> 
    <match url="(.*)" /> 

    <conditions logicalGrouping="MatchAny"> 
     <add input="{HTTPS}" pattern="OFF" /> 
     <add input="{HTTP_HOST}" pattern="^example\.com$" /> 
    </conditions> 

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" /> 
</rule> 

<rule name="Canonical Host Name (HTTPS)" stopProcessing="true"> 
    <match url="(.*)" /> 

    <conditions logicalGrouping="MatchAny"> 
     <add input="{HTTPS}" pattern="ON" /> 
     <add input="{HTTP_HOST}" pattern="^example\.com$" /> 
    </conditions> 

    <action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" /> 
</rule> 

Luego, repetí el par de reglas arriba para los nombres de dominio alternativos.

+2

Creo que quisiste decir "MatchAll" en lugar de "MatchAny". De lo contrario, te quedas atascado en un ciclo de muerte y tu página deja de cargarse. –

+0

La primera regla debería significar "si el patrón HTTPS está desactivado *** Y *** la url HTTP_HOST se parece a este patrón". La segunda regla debería significar "si el patrón HTTPS está desactivado *** Y *** la URL HTTP_HOST se parece a este patrón". –

+0

@Scott Mitchel ¿podría escribir alguna explicación también ... para los símbolos utilizados en el patrón? –

6

Si solo desea redirigir en función del protocolo utilizado actualmente (según su última muestra), entonces hay una solución mucho más simple que reducirá a la mitad la cantidad de reglas que necesitará. Lo siguiente es lo que aprendí de un colega mío.

Como has visto, el argumento {HTTPS} contendrá el valor ENCENDIDO o APAGADO. Puede asignar este valor a https: // o http: // introduciendo este valor en un rewritemap.

Así es como esto funcionaría:

1- Crear una sección RewriteMap para el mapeo de la {HTTPS} Valor:

<rewriteMap name="MapProtocol" defaultValue="OFF"> 
     <add key="ON" value="https://" /> 
     <add key="OFF" value="http://" /> 
    </rewriteMap> 

le toca a usted decidir si desea que sólo incluir el protocolo, o el punto y coma y las barras diagonales también. No importa la solución, pero téngalo en cuenta siempre que se refiera a él.

2- Consulte este mapa donde lo necesite. En esta muestra se utiliza en salientes-reglas, sino que también va a trabajar en su escenario:

<rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml"> 
     <match filterByTags="A, Link, Script" pattern="YOUR PATTERN" /> 
     <action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" /> 
    </rule> 

Eso es todo, el módulo de reescritura de URL debe ahora utilizar automagicamente el protocolo correcto para sus enlaces dependiendo de si estás usando https, o, por supuesto, http.

Espero que esto ayude!

+0

Esto definitivamente mejora la respuesta de Scotts. Haré una tercera respuesta combinando ambas respuestas para mostrar cómo debería ser la configuración. –

36

Aquí está la respuesta de Scott con las mejoras de Hasan. Esto debería cubrir sitios mixtos SSL/no SSL. La regla básicamente dice "si la url no tiene www.example.com", haz una redirección permanente a ella. Básicamente ... está redirigiendo a las personas que lo visitan sin www o directamente a su dirección IP.

<rewrite> 
<rules> 
    <rule name="Canonical Host Name" stopProcessing="true"> 
     <match url="(.*)" /> 
     <conditions logicalGrouping="MatchAll"> 
      <add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" /> 
     </conditions> 
     <action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" /> 
    </rule> 
</rules> 
<rewriteMaps> 
    <rewriteMap name="MapSSL" defaultValue="http://"> 
     <add key="ON" value="https://" /> 
     <add key="OFF" value="http://" /> 
    </rewriteMap> 
</rewriteMaps> 
</rewrite> 
+0

Supongo que 'rewriteMap' debería tener' defaultValue = "http: //" ', not' "OFF" '. – Douglas

+0

@Douglas El atributo [ 'defaultValue'] (https://www.iis.net/learn/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module) especifica el parámetro de entrada predeterminado , no devuelve valor En este caso, "OFF" es el valor predeterminado si no se pasa ninguno. – rdev5

+0

@MattBorja: ¿Estás seguro? '' "El atributo' defaultValue' especifica qué valor usar si no se ha definido una URL entrante en el mapa. En este caso, se devolverá una cadena vacía. " – Douglas

1

he aquí una solución entre dominios que funciona no sólo en example.com sino también en cualquier dominio

<rewrite> 
    <rules> 
     <rule name="Canonical Host Name" stopProcessing="true"> 
      <match url="(.*)" /> 
      <conditions logicalGrouping="MatchAll"> 
       <add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" /> 
      </conditions> 
      <action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" /> 
     </rule> 
    </rules> 
    <rewriteMaps> 
     <rewriteMap name="MapProtocol" defaultValue="OFF"> 
      <add key="ON" value="https://" /> 
      <add key="OFF" value="http://" /> 
     </rewriteMap> 
    </rewriteMaps> 
</rewrite> 
Cuestiones relacionadas