2010-04-09 17 views
21

Pracuję nad witryną, która korzysta z funkcji przepisywania adresów URL w IIS 7, aby wykonać stałe przekierowanie z witryny example.com na www.example.com, a także przepisać podobne nazwy domen na "główne", na przykład z www.examples.com to www.example.com.Przepisywanie adresów URL w IIS7: Jak nie rezygnować z protokołu HTTPS z przepisanego adresu URL?

Ta reguła przepisywania - poniżej - pracował dobrze przez jakiś czas. Jednak ostatnio dodaliśmy obsługę HTTPS i zauważyliśmy, że jeśli użytkownicy odwiedzą jeden z adresów URL, które mają zostać przepisane do witryny www.example.com, to HTTPS zostanie usunięty. Na przykład, jeśli użytkownik odwiedza https://example.com, zostanie przekierowany na numer http://www.example.com, a my chcielibyśmy, aby zostały wysłane do https://www.example.com.

Oto reguła przepisywania zainteresowania (w pliku 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> 

Jak widać, url elementu Action Punkty atrybutów bezpośrednio na stronę http: //, więc mam dlaczego https://example.com jest przekierowywany do http://www.example.com. Moje pytanie brzmi: jak to naprawić? Próbowałem (naiwnie) po prostu usunąć część http: // z atrybutu url, ale to nie zadziałało.

+0

Wydaje się, że po prostu pozostawiając 'http: //' z URL przekierowania spowoduje IIS 7.5 korzystać z protokołu żądania przychodzącego. – HABO

Odpowiedz

10

Wyjaśniłem odpowiedź z pomocą moich kolegów.

musiałem korzystać z wielu zasad warunku na {HTTPS}. Zwróć uwagę na warunek {HTTPS} w poniższych regułach.

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

Powtórzyłem powyższą parę reguł dla alternatywnych nazw domen.

+2

Sądzę, że miałeś zamiar powiedzieć "MatchAll" zamiast "MatchAny". W przeciwnym razie utkniesz w stanie śmierci, a twoja strona przestanie się ładować. –

+0

Pierwsza reguła powinna oznaczać "jeśli jest wyłączona HTTPS *** ORAZ *** URL HTTP_HOST wygląda tak jak ten wzór". Druga zasada powinna oznaczać "jeśli jest to wzorzec HTTPS *** ORAZ *** URL HTTP_HOST wygląda tak jak ten wzór". –

+0

@Scott Mitchel czy napiszecie też jakieś wyjaśnienie ... dla symboli używanych we wzorze? –

6

Jeśli chcesz tylko przekierować na podstawie aktualnie używanego protokołu (jak na ostatnim przykładzie), istnieje znacznie prostsze rozwiązanie, które zmniejszy o połowę ilość potrzebnych reguł. Oto, czego nauczyłem się od kolegi z mojej firmy.

Jak widać, argument {HTTPS} będzie zawierał wartość WŁ. Lub WYŁ. Możesz odwzorować tę wartość na https: // lub http: //, podając tę ​​wartość w przepisanej wersji.

Oto jak to będzie działać:

1- Tworzenie sekcję rewritemap odwzorowywania {HTTPS} wartość:

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

to do ciebie, aby zdecydować, czy chcesz tylko to protokół, lub także średniki i ukośne przekroje. Nie ma to znaczenia dla rozwiązania, ale pamiętaj o tym, gdziekolwiek go znajdziesz.

2- Zobacz tę mapę, gdziekolwiek chcesz. W tym przykładzie jest używany w wychodzących zasadami, ale to również pracować w swoim scenariuszu:

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

To jest to, moduł URL Rewrite powinien teraz automagicznie wykorzystać odpowiedni protokół dla linków zależności od tego czy jesteś przy użyciu https lub, oczywiście, http.

Mam nadzieję, że to pomoże!

+0

To zdecydowanie poprawia odpowiedź Scotts. Zrobię trzecią odpowiedź, łączącą obie twoje odpowiedzi, aby pokazać, jak powinna wyglądać konfiguracja. –

36

Oto odpowiedź Scotta z poprawkami Hasana. Powinno to dotyczyć mieszanych witryn SSL/nie-SSL. Reguła mówi "jeśli adres URL nie ma www.example.com", wykonaj stałe przekierowanie. Zasadniczo ... przekierowujesz osoby, które odwiedzają Cię bez www lub bezpośrednio pod swoim adresem 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

Zakładam, że 'przepisanieMap' powinien mieć wartość' defaultValue = "http: //" ', a nie' "OFF" '. – Douglas

+0

@Douglas Atrybut ['defaultValue'] (https://www.iis.net/learn/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module) określa domyślny parametr wejściowy , nie zwraca wartości. W tym przypadku "WYŁ" jest wartością domyślną, jeśli żadna nie jest przekazywana. – rdev5

+0

@MattBorja: Jesteś pewien? '' "Atrybut' defaultValue' określa, jakiej wartości użyć, jeśli adres URL nie został zdefiniowany na mapie, w takim przypadku zostanie zwrócony pusty łańcuch. " – Douglas

1

Oto rozwiązanie cross-domain, która działa nie tylko na example.com ale również na dowolnej domeny

<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> 
Powiązane problemy