htaccess wyklucza jeden adres URL z Basic Auth

79

Muszę wykluczyć jeden adres URL (lub jeszcze lepiej jeden prefiks) z normalnej ochrony htaccess Basic Auth. Coś w stylu /callbacks/myBanklub /callbacks/.* Czy masz jakieś wskazówki, jak to zrobić?

Nie szukam sposobu wykluczenia pliku. Musi to być adres URL (ponieważ jest to rozwiązanie oparte na frameworku PHP, a wszystkie adresy URL są przekierowywane mod_rewritedo index.php). Więc nie ma pliku pod tym adresem URL. Nic.

Niektóre z tych adresów URL to po prostu wywołania zwrotne z innych usług (adres IP nie jest znany, więc nie mogę wykluczyć na podstawie adresu IP) i nie mogą monitować o użytkownika / hasło.

Obecna definicja jest tak prosta, jak:

AuthName "Please login."
AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /xxx/.htpasswd
require valid-user 
KrzysDan
źródło

Odpowiedzi:

59

Jeśli używasz Apache 2.4 SetEnvIfi obejścia mod_rewrite nie są już potrzebne, ponieważ Requiredyrektywa może bezpośrednio interpretować wyrażenia:

AuthType Basic
AuthName "Please login."
AuthUserFile "/xxx/.htpasswd"

Require expr %{REQUEST_URI} =~ m#^/callbacks/.*#
Require valid-user

Apache 2.4 traktuje Requiredyrektywy, które nie są pogrupowane według, <RequireAll>tak jakby znajdowały się w <RequireAny>instrukcji, która zachowuje się jak instrukcja „lub”. Oto bardziej skomplikowany przykład, który demonstruje dopasowanie zarówno identyfikatora URI żądania, jak i ciągu zapytania, a także wymaganie prawidłowego użytkownika:

AuthType Basic
AuthName "Please login."
AuthUserFile "/xxx/.htpasswd"

<RequireAny>
    <RequireAll>
        # I'm using the alternate matching form here so I don't have
        # to escape the /'s in the URL.
        Require expr %{REQUEST_URI} =~ m#^/callbacks/.*#

        # You can also match on the query string, which is more
        # convenient than SetEnvIf.
        #Require expr %{QUERY_STRING} = 'secret_var=42'
    </RequireAll>

    Require valid-user
</RequireAny>

Ten przykład umożliwiłby dostęp, /callbacks/foo?secret_var=42ale wymagałby nazwy użytkownika i hasła /callbacks/foo.

Pamiętaj, że jeśli nie użyjesz <RequireAll>, Apache spróbuje dopasować każdy Require w kolejności, więc zastanów się, na które warunki chcesz zezwolić w pierwszej kolejności.

Odniesienie do Requiredyrektywy znajduje się tutaj: https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require

A exprodniesienie do sesji jest tutaj: https://httpd.apache.org/docs/2.4/expr.html

beporter
źródło
3
Musiałem usunąć podwójne cudzysłowy wokół wyrażenia Wymagaj, aby działało na Apache 2.4.7. Poza tym działało idealnie.
Scott Smith
Ja też musiałem usunąć podwójne cudzysłowy, ale zadziałało idealnie.
TMPilot
1
Nie działa na mojej instalacji Apache 2.4.10 / cakephp 3. Chcę wykluczyć / odpocząć, co jest ścieżką wirtualną (reguła przepisywania). Nie mogę zrozumieć, dlaczego to nie działa.
Stephan Richter,
3
Podejrzewam, że @ stephan-richter, ponieważ %{REQUEST_URI}wartość jest przepisanym ciągiem. W przypadku Cake 3 kończy się to prawie zawsze /webroot/index.php. Być może będziesz musiał wymyślić alternatywne podejście, takie jak użycie samego Cake do obsługi uwierzytelniania tras.
beporter
Masz rację. Opublikowałem pytanie dotyczące tego problemu i sam znalazłem odpowiedź: stackoverflow.com/questions/41077895/ ...
Stephan Richter
85

Używając SetEnvIf , możesz utworzyć zmienną, gdy żądanie zaczyna się od jakiejś ścieżki, a następnie użyć Satisfy Anydyrektywy, aby uniknąć konieczności logowania.

# set an environtment variable "noauth" if the request starts with "/callbacks/"
SetEnvIf Request_URI ^/callbacks/ noauth=1

# the auth block
AuthName "Please login."
AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /xxx/.htpasswd

# Here is where we allow/deny
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth

Fragment dyrektywy allow / deny w dyrektywach mówi, że odmawia dostępu KAŻDEMU , z wyjątkiem sytuacji, gdy istnieje poprawny użytkownik (pomyślne logowanie BASIC) lub gdy noauthzmienna jest ustawiona.

Jon Lin
źródło
Dodałem tę sekcję w <VirtualHost *: 80> DocumentRoot / var / www / Symfony / web / <Directory / var / www // Symfony / web>, ale nie działa.
vishal
Czy mógłbyś wyjaśnić, dlaczego <Files> tutaj nie działa?
asdmin
1
Dzięki! Naprawdę mi pomogło, uważaj na przypadek - miałem Order deny,allowi to nie zadziała. Nie trzeba dodawać, że bardzo frustrujące!
James F
2
może wymagać Allow from env=REDIRECT_noauthponownego zapisania adresów URL. To mógł być problem z @vishal. Zajrzyj tutaj: [ stackoverflow.com/a/41092497/1285585]
Stephan Richter,
2
Potrzebuję obu linii Allow from env=noauthi Allow from env=REDIRECT_noauthżeby to działało.
CDuv,
6

To rozwiązanie działa całkiem nieźle, wystarczy zdefiniować białą listę, przez którą chcesz przejść.

SetEnvIfNoCase Request_URI "^/status\.php" noauth

AuthType Basic
AuthName "Identify yourself"
AuthUserFile /path/to/.htpasswd
Require valid-user

Order Deny,Allow
Deny from all
Allow from env=noauth

Satisfy any
Nick Z
źródło
4

Wypróbowałem inne rozwiązania, ale to zadziałało. Miejmy nadzieję, że pomoże to innym.

# Auth stuff
AuthName "Authorized personnel only."
AuthType Basic
AuthUserFile /path/to/your/htpasswd/file

SetEnvIf Request_URI "^/index.php/api/*" allow
Order allow,deny
Require valid-user
Allow from env=allow
Deny from env=!allow
Satisfy any

Umożliwi to /index.php/api/otwarcie adresu URL interfejsu API i dowolnego ciągu adresu URL bez konieczności logowania się, a cokolwiek innego zostanie poproszone o zalogowanie.

Przykład:

mywebsite.com/index.php/apiotworzy się bez monitu o zalogowanie mywebsite.com/index.php/api/soap/?wsdl=1się otworzy bez pytania o zalogowanie mywebsite.comzostanie wyświetlony monit o zalogowanie się w pierwszej kolejności

MagentoMan
źródło
1
<location />
        SetEnvIf Request_URI "/callback/.*" REDIRECT_noauth=1

        AuthType Basic
        AuthName "Restricted Files"
        AuthUserFile /etc/httpd/passwords/passwords
        Order Deny,Allow
        Satisfy any
        Deny from all
        Allow from env=REDIRECT_noauth
        Require user yournickname
</location>
bluszcz
źródło
0

Inne podejście działa w ten sposób, jeśli chroniony obszar ma monolityczny skrypt PHP kontrolujący wszystko, na przykład Wordpress. Skonfiguruj uwierzytelnianie w innym katalogu. Umieść tam plik index.php, który ustawia plik cookie na ścieżce „/”. Następnie w Wordpress (na przykład) sprawdź plik cookie, ale pomiń sprawdzanie, czy $ _SERVER ['REQUEST_URI'] jest wykluczonym adresem URL.

Na mojej wspólnej platformie hostingowej RewriteRule nie może ustawić zmiennej środowiskowej, która działałaby z „Satisfy any”.

Przy każdym podejściu uważaj, że chroniona strona nie zawiera obrazów, arkuszy stylów itp., Które powodują żądanie uwierzytelnienia, gdy sama strona nie.

kitchin
źródło
0

Dodaj poniższy kod do głównego pliku htaccess i nie zapomnij zmienić adresu URL administratora, strony pliku .htpasswd.

<Files "admin.php">
        AuthName "Cron auth"
        AuthUserFile E:\wamp\www\mg\.htpasswd
        AuthType basic
        Require valid-user
    </Files>

Utwórz plik .htpasswd w folderze głównym i dodaj poniżej nazwę użytkownika i hasło (ustaw domyślną nazwę użytkownika: admin i hasło: admin123)

admin:$apr1$8.nTvE4f$UirPOK.PQqqfghwANLY47.

Daj mi znać, jeśli nadal masz jakiś problem.

Gnidy
źródło
0

dlaczego po prostu nie użyjesz uwierzytelniania podstawowego zgodnie z przeznaczeniem?

user:[email protected]/callbacks/etc
ryaan_anthony
źródło
1
Cóż, ponieważ a) nikt tak naprawdę nie chce danych uwierzytelniania ™ w łańcuchu URI oraz b) ponieważ jest prawdopodobne, że OP nie ma możliwości dostosowania połączenia (ponieważ mówi o wywołaniach zwrotnych z banku, zakładam, że nie może zmienić zachowanie po stronie klienta)
frank42