Выполните HTTP-аутентификацию через HTTPS с переписыванием URL
-
19-09-2019 - |
Вопрос
Я пытаюсь защитить ~/public_html/dev
каталог, использующий http auth basic, но для обеспечения безопасности я хочу запустить его через ssl.
Средняя часть приведенного ниже .htaccess
файл переключается на https, если URI запроса начинается с /dev
и работает.
Последний раздел файла также работает, но не работает должным образом с перенаправлением https.
В принципе, я хочу иметь возможность печатать http://www.example.com/dev/some_sub_dir/
и быть перенаправленным на https://www.example.com/dev/some_sub_dir/
и запросил имя пользователя и пароль http auth.
Что в данный момент произойдет, так это если я перейду к http://www.example.com/dev/some_sub_dir/
Я получаю запрос на ввод имени пользователя и пароля через порт 80, а затем сразу же получаю запрос снова через порт 443.Таким образом, мои учетные данные отправляются дважды, один раз в открытом виде и один раз в зашифрованном.Переписывать весь URL-адрес https немного бессмысленно.
Причина этого заключается в том, что я не смогу случайно отправить своего пользователя / передать по http;https всегда будет использоваться для доступа к /dev
справочник.
Тот самый .htaccess
находится в ~/public_html/dev
справочник.
# Rewrite Rules for example.com RewriteEngine On RewriteBase / # force /dev over https RewriteCond %{HTTPS} !on RewriteCond %{REQUEST_URI} ^/dev RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} # do auth AuthType Basic AuthName "dev" AuthUserFile /home/matt/public_html/dev/.htpasswd Require valid-user
Решение
Существует относительно популярный способ принудительно использовать HTTPS перед выполнением базовой аутентификации.Я впервые увидел это здесь:
http://blog.jozjan.net/2008/02/htaccess-redirect-to-ssl-https-before.html
Это включает в себя использование пользовательского документа об ошибке для обработки всего, что происходит после сбоя проверки HTTPS.
Например, у меня есть единственная страница, на которой мне нужно принудительно использовать HTTPS, поэтому я сделал это в файле .htaccess:
<FilesMatch "secure-page.php">
SSLRequireSSL
ErrorDocument 403 https://www.example.com/secure-page.php
AuthType Basic
AuthName "Secure Page"
AuthUserFile /var/www/whatever/.htpasswdFile
Require valid-user
</FilesMatch>
Что переводится как:
если запрашиваемая страница является 'secure-page.php ' - если не HTTPS, то перенаправьте на пользовательскую "страницу ошибки" - "страница ошибки" на самом деле является просто HTTPS-версией страницы - при втором запросе, поскольку проверка HTTPS теперь пройдена, выполните базовую аутентификацию :)
Вы можете распространить эту концепцию на каталог или другие варианты использования - вашей пользовательской "страницей ошибки" может быть php-страница, которая перенаправляет на правильный HTTPS URL, или CGI-скрипт, подобный приведенной выше ссылке...
Другие советы
Я столкнулся с той же проблемой и, наконец, нашел уродливое решение, но оно работает.Поместите правило перезаписи в директиву каталога в httpd.conf или в один из ваших файлов conf.d (т.е. в "Основную" конфигурацию сервера).Затем поместите строки Auth* и Require в директиву Directory внутри тот самый <VirtualHost _default_:443>
контейнер в ssl.conf (или где бы ни был определен ваш SSL VirtualHost).
Для меня это означает создание файла /etc/httpd/conf.d/test.conf
с:
<Directory "/var/www/html/test">
#
# force HTTPS
#
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Directory>
...а затем добавляем следующее внутри /etc/httpd/conf.d/ssl.conf
чуть выше </VirtualHost>
тег:
<Directory "/var/www/html/test">
#
# require authentication
#
AuthType Basic
AuthName "Please Log In"
AuthUserFile /var/www/auth/passwords
Require valid-user
</Directory>
Выполнение этого заставляет Apache применять RewriteRule ко всем запросам, а требования аутентификации - только к запросам в 443 VirtualHost.
Основываясь на ответе siliconrockstar, я добавляю php-скрипт, который будет работать в случае, когда вы хотите принудительно включить SSL ВСЕ файлы, а не только один файловый кейс, показанный siliconrockstar.Здесь он снова работает совместно с файлом htaccess.
Htaccess для защиты всего каталога:
SSLRequireSSL
ErrorDocument 403 /yourphp.php
AuthType Basic
AuthName "Secure Page"
AuthUserFile /some_path_above_the_html_root/.htpasswdFile
Require valid-user
php, вызываемый htaccess (путь, указанный для php в этом примере htaccess, является корневым каталогом вашего сайта), который принудительно использует https для вызванного вами URL:
<?php
$path = "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
if ( $_SERVER['SERVER_PORT'] == 80) {
header("Status: 302 Moved\n");
header("Location: ".$path."\n\n");
}
else {
header( "Content-type: text/html\n\n");
echo "How did you get here???";
}
?>
Если на вашем сайте нет SSL-сертификата, вам придется его установить.Если это ваше единственное применение, вы можете установить самозаверяющий сертификат.На cPanel VPS с вашим сайтом на выделенном IP-адресе это занимает считанные минуты:в WHM посетите
Один.Создайте SSL-сертификат и запрос на подпись
тогда
Два.Установите SSL-сертификат в Домене
Защита содержимого с помощью базовой аутентификации никогда не будет надежно работать по протоколу HTTP.
После того, как пользователь ввел свое имя пользователя и пароль, оно отправляется в незашифрованном виде при каждом просмотре страницы на этом сайте - оно не просто отправляется в момент получения пользователем запроса.
Вы должны рассматривать запросы по протоколу HTTP как неаутентифицированные и выполнять ВСЕ вход в систему осуществляется по протоколу HTTPS.
Многие веб-сайты используют HTTPS для входа в систему - используя формы и файлы cookie, а не обычный auth, - а затем переходят на HTTP.Это означает, что их файл cookie "вы вошли в систему" отправляется в незашифрованном виде.Из-за этого каждая ценная цель была взломана, и gmail теперь переходит на полный HTTPS, и за ним последуют другие.
У вас нет тех же проблем с масштабированием, которые были у других, что удерживало их от более дорогостоящего в вычислительном отношении HTTPS.Если ваша домашняя страница поддерживает доступ по протоколу HTTPS, используйте его повсюду.
Если вы разместите правила перезаписи в основной конфигурации, за пределами каких-либо или или аналогичных, перезапись будет выполнена перед аутентификацией.
Видишь Технология переписывания
Работает ли поместить ваш раздел аутентификации в <Location>
или <LocationMatch>
тег, использующий протокол в качестве термина?
Я обходлю это таким образом.Просто разрешите не использовать SSL, так как он будет перенаправлен, а затем потребует авторизации один раз по SSL...
SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
AuthUserFile /.htpasswd
AuthName "Enter your Username and Password:"
AuthType Basic
require valid-user
Allow from env=IS_NON_SSL
Я знаю, что это старый вопрос, но у меня возникли проблемы с простым перенаправлением ht.access.После многих других проблем и ответов я, наконец, собрал этот htaccess, который работает так, как задумано.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
AuthName "Private Server"
AuthUserFile /var/www/.htpassword
AuthType Basic
require valid-user
Order allow,deny
Allow from env=!HTTPS
Satisfy Any
Чтобы отметить
Order allow,deny
Именно этого не хватало во многих других ответах, которые я видел, поскольку это позволяло бы людям входить напрямую при использовании https.Другим разделом, который отсутствовал в моих тестах, был следующий:
Satisfy Any
Этот следующий фрагмент - это то, что позволяет клиентам, не использующим SSL, использовать with для перенаправления.Параметр HTTPS env устанавливается из mod_ssl для ssl-клиентов.
Allow from env=!HTTPS
У меня есть два ответа на этот вопрос, один с мышлением 2010 года, а другой с мышлением после 2012 года.
Ответить на этот вопрос так, как если бы он был задан в 2010 году:используйте две разные конфигурации виртуального хостинга.
Это решение немного выходит за рамки вопроса, поскольку подразумевается, что "У меня есть доступ только к изменению .htaccess
!" но жизнеспособным решением во многих случаях является просьба к рабочему администратору просто настроить две разные конфигурации виртуального хостинга.
Не-SSL VirtualHost не настроен для доступа к чему-либо в файловой системе и просто возвращает 301 перенаправление на
https://...
местоположения для всех запросов.После этого виртуальный хост, прослушивающий SSL, может свободно реализовать базовую аутентификацию, не беспокоясь о том, что стандартный HTTP-прослушиватель выдаст товар.
Однако, надев шляпу после 2018 года и отметив, что этот вопрос был задан до Apache 2.4 (в начале 2012 года?), пришло время для обновления.Представлен Apache 2.4 <If condition>
проверки, что делает это намного проще и непосредственнее:
Во-первых, не выполняйте ifмодулирование RewriteEngine.Поскольку Apache прослушивает оба порта 80 и 443 (в стандартной настройке), И мы хотим принудительно использовать SSL, мы хотим, чтобы сервер отключился, если модуль перезаписи иным образом отключен.
RewriteEngine On
Во-вторых, достаточно просто выполните немедленное и постоянное (301) перенаправление, если запрос небезопасен.Обратите внимание на R (edirect) и L (ast), которые работают вместе, гарантируя, что незашифрованные запросы перенаправляются и не могут быть использованы для получения доступа без проверки подлинности.(Для людей с ОКР, не склонных к копипастингу, обратите внимание на недостаток пространства между
!=
иon
.Это сделано намеренно.)RewriteCond %{HTTPS} !=on RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,QSA,L,NC]
Наконец, используйте ту же самую переменную с
<If-condition>
убедитесь, что нам требуется пароль только для запроса TLS.<If "%{HTTPS} == 'on'"> AuthName "Password please!" AuthType Basic AuthUserFile /path/to/htpasswdfile AuthGroupFile /dev/null require valid-user </If>
И в целом:
# .htaccess
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,QSA,L,NC]
<If "%{HTTPS} == 'on'">
AuthName "Password please!"
AuthType Basic
AuthUserFile /path/to/htpasswdfile
AuthGroupFile /dev/null
require valid-user
</If>