2012-06-17 23 views
12

Rozejrzałem się po Google i StackOverflow, aby uzyskać odpowiedź na to pytanie, ale fakt, że nie wiem zbyt wiele na temat .htaccess nie pomaga mi zdecydować, jakie poprawne odpowiedzi bo moja sytuacja jest, więc proszę o to tutaj.. Htaccess RewriteCond gdzie URI nie zawiera domeny

Moja sytuacja polega na tym, że mam kilka witryn, które używają tego samego katalogu fizycznego co katalog główny na serwerze.

Wszystko działa dobrze, ale chciałem się upewnić, że każda witryna nie ma dostępu do innych obrazów itp. Z przeglądarki, chyba że znajdują się we właściwej domenie.

Obecnie mam strukturę plików takiego:

/resources/{resource}/{full_domain_name} 

Tak na przykład www.domain.co.uk miałoby strukturę takiego:

http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

Ale jeśli www.domain_2.co.uk istnieje przy użyciu tego samego katalogu fizycznego na miejscu root, a następnie mogą przeglądać zasoby innej domeny z własnej domeny, na przykład:

http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

To naprawdę nie jest poważny problem, ponieważ nie ma absolutnie żadnych poufnych informacji przechowywanych w tych katalogach, ale jest to bardziej irytujące i wolałbym, żeby użytkownicy nie byli w stanie tego zrobić (nie, że ktokolwiek faktycznie miał do tej pory).

Próbowałem umieszczenie pliku .htaccess w katalogu/Resources ale utknąłem z wyrażeń regularnych itp

Zasadniczo chcę, aby upewnić się, że URI zawiera aktualną nazwę domeny inaczej przekierować do 403 strona błędu.

To właśnie wymyśliłem:

RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 
RewriteRule ^(.*)$ /error/403.php 

Powodem umieścić w [^/] nieco dlatego istnieje kilka folderów, na przykład:

/resources/images/{full_domain_name} 
/resources/scripts/{full_domain_name} 
/resources/stylesheets/{full_domain_name} 

Czy ktoś może mi pomóc z tymi warunki?

Każda pomoc zostanie doceniona.

+0

Jaki jest wynik Twojej obecnej reguły? Wygląda na to, że zadziała, z wyjątkiem tego, że nie potrzebujesz żadnego '()' wokół '/ resources/[^ /] * /% {HTTP_HOST}. *' –

+0

@Michael Aktualnie, jeśli jestem na www.domain.co .uk i przejdź na stronę www.domain.co.uk/resources/stylesheets/www.domain.co.uk/style.css, na przykład zawsze przekierowuje mnie do pliku /error/403.php. Kiedy usuwam regułę .htaccess, znajduje plik tak, jak powinien normalnie. –

+0

W rzeczywistości nie potrzebujesz całego '% {REQUEST_URI}' reprezentowanego w wyrażeniu regularnym. Możesz po prostu dopasować http_host 'RewriteCond% {REQUEST_URI}! ^. +% {HTTP_HOST}' –

Odpowiedz

10

To jest wspaniałe pytanie, a gdybym mogła, wznowiłbym 10+ razy. Zamieszczam moją odpowiedź, mimo że masz tu zaakceptowaną odpowiedź, ponieważ naprawdę musiałem przeglądać wszystkie moje zasoby Apache, aby znaleźć odpowiedź. Oto reguła będzie trzeba do tego problemu:

Options +FollowSymLinks -MultiViews 
# Turn mod_rewrite on 
RewriteEngine On 
RewriteBase/

RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC] 
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE] 

PS: Ponieważ nie możemy używać % zmiennych na RHS jako back-odniesienia używam regex specjalną zmienną back-odniesienia \1 w RewriteCond tutaj.

+1

Zazwyczaj nie robię tego, ale w tym przypadku myślę, że zmienię moja zaakceptowana odpowiedź, ponieważ stanowi to idealne rozwiązanie problemu. Dziękuję za opublikowanie Twojej odpowiedzi anubhava, jest to bardzo doceniane! –

+0

Serdecznie witam i dziękuję za opublikowanie tak interesującego problemu, który sprawił, że nauczyłem się nowych sztuczek mod_rewrite :). – anubhava

3

Ten warunek jest niewystarczający:

RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 

Bo jeśli żądać niczego, co nie zacząć /resources/, Wezmę stronę 403.php błędzie. Co naprawdę chcesz coś takiego:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{HTTP_HOST} !%1 

Albo

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/ 

Gdzie pierwszy warunek jest sprawdzenie, czy wniosek jest dla zasobu, a następnie drugi sprawdzanie hosta. JEDNAK, żadna z nich nie zadziała, ponieważ dyrektywa mod_rewrite RewriteCond nie zezwala na % zmiennych lub odwołań wstecz po prawej stronie warunku, tylko po lewej stronie.Podobnie, nie można tego zrobić albo:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php 

Ponieważ wyraz twarzy RewriteRule nie może mieć zmienne w nim, ponieważ jest to wyrażenie regularne, i to dosłownie oczekuje %{HTTP_HOST} zamiast zastępując ją hostii wskazanym w żądaniu. Podsumowując, nie, nie można tego zrobić przy użyciu warunków mod_rewrite w ten sposób.

Coś, co można wypróbować, jeśli masz dostęp do konfiguracji serwera lub konfiguracji vhost, to utworzenie RewriteMap i przekazanie obu %{REQUEST_URI} i %{HTTP_HOST}. Więc jeśli mapa nazywa check_host następnie reguła może wyglądać następująco:

RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}} 

A twój skrypt wystarczy przeprowadzić analizę danych wejściowych, podzielić ją od pierwszego _, analizować żądania URI i upewnić hosta jest taki sam jak HTTP_HOST. Jeśli jest taki sam, wyprowadź ten sam identyfikator URI żądania, w przeciwnym razie wygeneruj identyfikator URI błędu. Jeśli nie masz dostępu do serwera lub konfiguracji vhost, myślę, że masz pecha. Nie można zdefiniować zapisu RewriteMap w pliku htaccess.

+0

Dziękuję za tę odpowiedź Jon Lin. Nie wiedziałem, że nie można umieścić zmiennych% lub odnośników z powrotem w prawej części RewriteCond. Zdecydowałem się wypróbować RewriteMap, ale jeśli z jakiegokolwiek powodu nie mogę tego zrobić, jestem pewien, że znajdę inną drogę poza mod_rewrite :) –

Powiązane problemy