2012-04-22 39 views
21

To jest mój .htaccess:Apache .htaccess przekierowanie do HTTPS przed pytaniem do uwierzytelniania użytkownika

RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 

AuthUserFile /etc/hi 
AuthName "hi" 
AuthType Basic 
require valid-user 

Pyta do uwierzytelniania użytkowników za pomocą protokołu HTTP, co oznacza, że ​​hasło zostanie wysłane w postaci zwykłego tekstu. To spowoduje przekierowanie do wersji https i ponownie poprosi o hasło.

Jak mogę to naprawić?

+2

trzeba mieć HTTP i HTTPS witryn deklarowane w odrębnych wpisów hostów wirtualnych, więc config dla jednego nie będzie kolidować z innym . Po zakończeniu, reguła przepisywania powinna znajdować się w http jeden, a uwierzytelnianie w https jeden (to wszystko zakłada, że ​​uzyskujesz dostęp do strony tylko przez HTTPS). – LazyOne

Odpowiedz

8

Obejmuję to w ten sposób. Wystarczy pozwolić Non-SSL, ponieważ zostanie on przekierowany następnie wymagać auth raz na SSL ...

SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL 

RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 

AuthUserFile /etc/hi 
AuthName "hi" 
AuthType Basic 
require valid-user 
Allow from env=IS_NON_SSL 
+1

Eleganckie rozwiązanie nie do końca oczywistego problemu. Skończyło się na użyciu 'Allow from env =! HTTPS', gdzie HTTPS jest ustawiony na żądania SSL, ale ta sama zasada dotyczy. Dzięki. –

+1

SERVER_PORT nie jest opcją dostępną w dyrektywie SetEnvIf, zgodnie z dokumentacją na http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif –

+4

Co najmniej w moim przypadku nadal prosi o uwierzytelnienie dwa razy. – LWC

9

Jeśli używasz Apache 2.4 można użyć configuration sections rozwiązać to dość łatwo.

Eg ...

# Redirect to HTTPS 
RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] 

# Authenticate users only when using HTTPS 
# Enable for <v2.4 
# SSLRequireSSL 
# ErrorDocument 403 /secure-folder/ 
# Enable for >v2.4 
<If "%{HTTPS} == 'on'"> 
    AuthType Basic 
    AuthName "Special things" 
    AuthUserFile /etc/blah.htpasswd 
    # Prevent this 'Require' directive from overriding any merged previously 
    <IfVersion >= 2.4> 
     AuthMerging And 
    </IfVersion> 
    Require valid-user 
# Enable for >v2.4 
</If> 
+5

* Zdecydowanie tego nie rób. * Z powodu kolejności scalania dyrektyw ("" jest ostatnio scalane), uwierzytelnieni użytkownicy będą mieli dostęp do dowolnego pliku lub katalogu uprzednio zablokowanego przez '' lub ''! Na przykład, w przypadku zwykłych konfiguracji serwera, plik '.htaccess' będzie miał dostęp dla ważnych użytkowników. – alecov

+3

@Alek, Dodałem dyrektywę "Authmerging", która według mnie rozwiązuje problem, który podniosłeś. Dlatego wszyscy odwiedzający są nadal przekierowywani na HTTPS, ale wszelkie żądania HTTPS wymagają uwierzytelnienia użytkownika * dodatkowo * do istniejących ograniczeń dodanych przez wcześniej połączone dyrektywy lub . Co myślisz? – Molomby

+2

Nie przetestowałem tej konfiguracji, ale z dokumentacji wydaje mi się to w porządku, więc zabiorę ci z tego słowo. – alecov

2

webapp naszego klienta jest zainstalowany w swoim katalogu webuser. Autoryzacja jest obsługiwana przed regułami mod_rewrite (https://serverfault.com/a/443185/253111), a nie mogliśmy uzyskać akceptowanej odpowiedzi do pracy, więc mod_rewrite nie wydawało się opcją.

Ostatecznie wyraźnie wymagaliśmy protokołu SSL i użyliśmy katalogu głównego aplikacji przez HTTPS jako dokumenty błędów 403 i 404. Więc kiedy odwiedza się jakąkolwiek stronę za pośrednictwem HTTP (która jest nieautoryzowana, stąd 403) lub nieistniejącą stroną (404), jest przekierowywany do np. https://DOMAIN.TLD/~WEBUSER/admin.

To jest plik .htaccess z dodatkowymi informacjami w komentarzach.

### INFO: Rewrites and redirects are handled after authorisation 
### @link https://serverfault.com/a/443185/253111 

### INFO: Log out of a HTPASSWD session 
### This was not always possible, but Firefox and Chrome seem to end sessions 
### when a new one is trying to be using ie.: 
### https://logout:[email protected]/~WEBUSER/ 
### @link http://stackoverflow.com/a/1163884/328272 

### FORCE SSL: Explicitly require the SSL certificate of a certain domain to 
### disallow unsigned certificates, etc. ErrorDocument commands are used to 
### redirect the user to an HTTPS URL. 
### @link http://forum.powweb.com/showthread.php?t=61566 
SSLOptions +StrictRequire 
SSLRequireSSL 
SSLRequire %{HTTP_HOST} eq "DOMAIN.TLD" 

### HTPASSWD AUTHENTICATION 
AuthUserFile /var/www/vhosts/DOMAIN.TLD/web_users/WEBUSER/.htpasswd 
AuthType Basic 
AuthName "Hello" 
Require valid-user 

### ERROR DOCUMENTS: Redirect user in case of a 403/404. 
ErrorDocument 403 https://DOMAIN.TLD/~WEBUSER/admin 
ErrorDocument 404 https://DOMAIN.TLD/~WEBUSER/admin 
+0

Dlaczego potrzebujesz 'SSLRequire% {HTTP_HOST} eq" DOMAIN.TLD "'? W jakim przypadku to pomaga? Przy okazji: SSLRequire jest amortyzowany https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslrequire – Adam

1

Rozwiązanie Molomby działa w wersji 2.4 i wyższej, ale nie działa z obecną wersją Debiana 2.2.22.

Rozwiązania Ben's/Chris Heald również nie działały dla mnie w wersji 2.2.22, ale było to spowodowane inną konfiguracją zamówienia/spełnienia. Te ustawienia zmieniły się w wersji 2.4, a rozwiązanie wydaje się być niezgodne z wersją 2.4 i nowszą (przekierowanie działa, ale przeglądarka wyświetla tylko nieautoryzowany błąd bez pytania o dane uwierzytelniające).

Oto połączenie obu rozwiązań, które powinny działać w wersjach poniżej i powyżej 2,4:

RewriteEngine on 
RewriteOptions Inherit # rewrite rules from parent directories 
RewriteCond %{HTTPS} off 
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] 

AuthType Digest 
AuthName "private area" 
AuthDigestProvider file 
AuthUserFile /path/to/file/.htdigest 

<IfVersion < 2.4> 
    Order Deny,Allow 
    Deny from all 
    Satisfy Any # reset this to 'All' in custom <Files> and <Directory> directives that block access 
    Allow from env=!HTTPS 
    Require valid-user 
</IfVersion> 
<IfVersion >= 2.4> 
    <If "%{HTTPS} == 'on'"> 
     AuthMerging And 
     Require valid-user 
    </If> 
</IfVersion> 

Wymagania: mod_rewrite, mod_auth, mod_digest, mod_version

+0

Dobra myśl, ale nie działa (błąd 500), ponieważ nawet z LWC

+0

@LWC 1.) Języki programowania to zła metafora twojego punktu. Przykład licznika: można skompilować niepoprawny kod C, jeśli preprocesor usuwa nieprawidłowe sekcje. Jako użytkownik oczekiwałbym, że IfVersion będzie działał podobnie, nie oceniając jego zawartości. 2.) Miałem tej konfiguracji w użyciu od 2014-02 do 2014-09 z Apache 2.2.22. Mogło to być nieprawidłowe i mogło spowodować wpisy w dzienniku błędów (nie sprawdziłem), ale działało zgodnie z oczekiwaniami i nie odpowiedziało błędami 5xx. (Może działało to tylko z powodu wersji Debiana, która czasami różni się od wersji na wyższym poziomie.) – Istador

+0

Myślę, że nie wszystkie, tylko wiele z nich. Dziękuję za wyjaśnienie! – LWC

7

Dziękuję bardzo, Istador!

My Apache w wersji 2.2 (DSM 5.1 Synology NAS), więc te dwa nie działają na nim:

RewriteOptions Inherit 
IfVersion 

Po biorąc je (i sekcję wersji> = 2.4) na zewnątrz. Cała sprawa zaczęła działać dla mnie.

Istnieje wiele sugestii na ten temat. Spędziłem dwa dni, aby je wypróbować.

Ale tylko ten działa dla mnie.

Oto co zrobiłem:

RewriteEngine on 
RewriteCond %{HTTPS} off 
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] 

AuthType Basic 
AuthName "private area" 
AuthUserFile /path/to/file/.htdigest 

Order Deny,Allow 
Deny from all 
Satisfy Any 
Allow from env=!HTTPS 
Require valid-user 

Więc to przetestowany na Apache 2.2, Synology DSM 5.1.

+0

Proszę nie dodawać "dziękuję" jako odpowiedzi. Gdy masz już wystarczającą [reputację] (http://stackoverflow.com/help/whats-reputation), będziesz mógł [głosować na pytania i odpowiedzi] (http://stackoverflow.com/help/privileges/vote- w górę), które uznałeś za pomocne. – Ilya

+0

To dziwne. Zgodnie z dokumentacją Apache 2.2 dla [mod_rewrite] (http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions) (dla Apache 1.3 i nowszych) i [mod_version] (http: // httpd.apache.org/docs/2.2/mod/mod_version.html) (dla Apache 2.0.56 i późniejszych) obie dyrektywy powinny być prawidłowe, zakładając, że oba moduły są zainstalowane. – Istador

+2

@Ilaa. "Dziękuję" jest pomocne, ponieważ post odnosi się do ich konkretnego posta, co jest pomocne w zapewnieniu kontekstu czytelnikowi, takiemu jak ja. Bez tego czytelnik mógłby założyć, że bezpośrednio zajmuje się tylko postem PO. Oczywiście mogli po prostu zrobić "@Istador", aby być bardziej zwięzłym! – Patanjali

1

Używam Apache 2.2 i żadne z powyższych rozwiązań nie sprawdziło się u mnie. Znalazłem obejście dla mnie here. Zasadniczo, musisz ustawić SSLRequireSSL i użyć jakiegoś języka skryptów w ErrorDocument, aby przekierować użytkowników do HTTPS. Niestety, w moim przypadku działa to tylko podczas uzyskiwania dostępu do konkretnych plików na serwerze, to NIE działa, jeśli tylko domena jest dostarczona. Oto co zrobiłem:

AuthType Basic 
AuthName "Password Protected Area" 
AuthUserFile /my/path/to/.htpasswd 
#Require valid-user 

<FilesMatch "(^(?!ssl.php).*)"> 
     SSLRequireSSL 
     ErrorDocument 403 /ssl.php 
     Require valid-user 
</FilesMatch> 

regex w FileMatch opowiada Apache SSLRequireSSL dla wszystkich plików z wyjątkiem ssl.php - i przekazania użytkownikowi ssl.php jeśli próbuje uzyskać dostęp bez SSL.

Moja ssl.php wygląda następująco:

if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "" || $_SERVER['HTTPS'] == "off") 
{ 
     $redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; 
     header("HTTP/1.1 301 Moved Permanently"); 
     header("Location: $redirect"); 
     exit; 
} 

Co teraz się dzieje:

Ostatnim punktem jest to, co nie jestem zadowolony, jeśli ktoś ma rozwiązanie, że byłbym rad o tym słyszeć. Rzeczy, które próbowałem rozwiązać ten problem:

  • Zmieniono wyrażenie regularne na (^ $) | (^ (?! ssl.php). *), Aby jawnie dopasować puste ciągi. Nie działa
  • Dodano regułę przepisywania, aby przepisać pusty ciąg do index.php. To też nie działa.
3

Sprawdzona rozwiązanie https://stackoverflow.com/a/15940387/2311074 działa na Firefox na Ubuntu 16.04, ale to nie działa w Firefoksie na Win 7.

Jeśli chcesz chronić swój folder https://yourdomain.com/securefolder następnie trzeba utworzyć w tym folderze .htaccess o następującej treści:

RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 

SSLRequireSSL 
ErrorDocument 403 https://yourdomain.com/securefolder 
AuthType Basic 
AuthName "Admin" 
AuthUserFile /outside/your/www/folder/.htpasswd 
Require user admin Admin 

Jak to działa jest to, że gdy dzwonisz na stronie internetowej poprzez http:// zamiast https:// będzie przekierowanie do ERR lub stronę. Sztuką jest użycie poprawnego linku z https:// jako domyślnej strony błędu.

0

Żadne z powyższych nie działało dla mnie, ale tak się stało. Moją jedyną obawą jest to, czy istnieją pewne warunki, w których auth nie jest uruchamiany, umożliwiając dostęp do kogoś bez poświadczeń. Nie jestem pewny, czy są, ale może wy, szczęśliwi ludzie, możecie powiedzieć inaczej.

Ten kod przekierowuje użytkownika innego niż www na adres www i http na adres https, za pomocą.htaccess folder auth.

To jest zawartość pliku .htaccess w katalogu chcesz chronić:

RewriteEngine on 
# ensure www. 
RewriteCond %{HTTP_HOST} !^www\. [NC] 
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/foldername/$1 [L,R=301] 
# ensure https 
RewriteCond %{HTTP:X-Forwarded-Proto} !https 
RewriteCond %{HTTPS} !=on [NC] 
RewriteRule ^(.*)$ https://%{HTTP_HOST}/foldername/$1 [L,R=301] 

# Apache 2.4 If 
<If "%{HTTPS} == 'on' && %{HTTP_HOST} =~ /www/"> 
AuthType Basic 
AuthName "Protected folder" 
AuthUserFile "/home/etc/.htpasswds/public_html/foldername/passwd" 
require valid-user 
</If> 
Powiązane problemy