|
|||||||||||||||||||||||||
|
Ставим пароль на страницуДанная статья не претендует на какие-то откровения, все эти вещи достаточно очевидны и широко известны. Но получив за последнее время несколько вопросов об ограничении доступа к web-страницам, я решил свести ответы на них вместе. Итак, наша задача - установить пароль на доступ к некоторой странице. Начнем с самого примитивного способа, если можно так сказать, защиты - нескольких строчек на JavaScript'е. Код - что-то вроде var pass = prompt("Enter the Password:", "");
if (pass == null)
window.location = "bad.html";
else if (pass.toLowerCase() == "password")
window.location = "ok.html";
else
window.location = "bad.html";
Уровнем повыше расположена аналогичная система, реализованная на Java. Ниже приведен упрощенный исходный код. import java.applet.*;
import java.awt.*;
import java.net.*;
public class Password extends Applet
{
TextField login, password;
String Login = "login";
String Password = "Password";
public Password()
{
}
public void init()
{
Panel panel = new Panel();
panel.setLayout(new GridLayout(2,2));
login = new TextField(20);
password = new TextField(20);
panel.add(new Label("Login:"));
panel.add(login);
panel.add(new Label("Password:"));
panel.add(password);
add(panel);
add(new Button("Ok"));
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button)
{
String s;
if(login.getText().equals(Login) && password.getText().equals(Password) )
{
s = "http://www.webclub.ru/materials/pagepsw/ok.html";
}
else
{
s = "http://www.webclub.ru/materials/pagepsw/bad.html";
}
try
{
getAppletContext().showDocument(new URL(s));
}
catch(Exception e)
{
password.setText(e.toString());
}
return true;
}
return false;
}
}
Включив этот апплет в страницу, можно получить нечто такое:
Его можно сделать поумнее, завести для каждого пользователя отдельную страницу, заставить считывать данные из файла и т.д. Принципиальный недостаток - после того как человек попал на искомую страницу, никто не в силах запретить ему запомнить этот URL, так что средство это одноразовое. Конечно, можно запрятать страницу внутрь фрейма, чтобы URL не светился в строке адреса, но сами понимаете, от кого эта защита. Опять же, апплет полностью уходит к клиенту и в принципе полностью доступен для исследования. Последнего недостатка лишено решение, основанное на использовании CGI. Простенький скрипт на Perl'е выглядит примерно так: #!/usr/bin/perl
use CGI qw(:standard);
$query = new CGI;
$ok = 'ok.html';
$address = 'bad.html';
$login = "login";
$password = "password";
$l = $query->param("login");
$p = $query->param("password");
if(($p eq $password) && ($l eq $login))
{
$address = $ok;
}
print $query->redirect($address);
Пример использования:
Чтобы справиться с первым недостатком, можно динамически сформировать новую страницу на основе спрятанной где-то там внутри, не выдавая при этом URL. Модифицированный код: #!/usr/bin/perl use CGI qw(:standard); $query = new CGI; $ok = 'ok.html'; $address = 'bad.html'; $docroot = $ENV{'DOCUMENT_ROOT'}; $localpath = "/materials/pagepsw/"; $login = "login"; $password = "password"; $l = $query->param("login"); $p = $query->param("password"); if(($p eq $password) && ($l eq $login)) { $address = $ok; } print $query->header(); open (FL, $docroot.$localpath.$address); while(<FL>) { # Здесь заодно можно на лету модифицировать html-код # Зачем ? Ну мало ли... :) print $_; } close (FL); Пример использования:
Как видно, URL файла уже не светится, правда ценой SSI, если что-то подобное присутствовало (впрочем, это как раз можно отлавливать при выводе и обрабатывать вручную). Но и здесь остается теоретическая возможность угадывания URL, при этом не надо забывать, что медвежью услугу могут сослужить всевозможные картинки, включаемые в страницы - при использовании относительных путей, конечно. Наконец, наиболее надежный способ установки пароля на доступ - это воспользоваться средствами сервера - не зря ж их люди делали, в конце концов. Остановлюсь на двух - Апаче как самом популярном и IIS как тоже популярном :) С IIS все совсем просто - защита осуществляется средствами NTFS, что, конечно, несколько ограничивает возможности не-администраторов сервера. Идея следующая: у пользователя IUSR_xxxx, под аккаунтом которого по умолчанию работают все посетители узла, отбирается доступ к желаемому файлу/каталогу. После чего доступ к этим файлам будут иметь только те пользователи, для которых это явно указано в Properties->Security. Понятно, что их гораздо удобнее объединять в группы. Здесь есть пара тонкостей. Во-первых, указанным пользователям должно быть дано право Logon locally (Policies->User Rights в User Manager'е). Во-вторых, если не выбрать в настройках WWW service Basic authentication (Clear Text), внутрь будут пропущены только пользователи Internet Explorer'а. В Apache все делается несколько иначе. Защита ставится на уровне каталогов. Соответствующие директивы могут быть помещены как в в общий конфигурационный файл (в разделе <Directory>), так и в файлы .htaccess. Набор директив в обоих случаях одинаков, а для большинства людей, арендующих место под сайт/страницу на чужом сервере, гораздо актуальнее второй способ. Итак, вы создаете в каталоге, доступ к которому планируется ограничить, файл .htaccess, после чего вставляете в него следующие директивы (привожу основные): AuthType тип контроля - обычно используется Basic. AuthName имя - задает имя области, в которой действительны имена и пароли пользователей. Это то самое имя, которое броузер показывает в диалоге ввода пароля. Задав одно такое имя для разных каталогов, можете сэкономить пользователям время по вводу лишнего пароля. AuthGroupFile имя
- задает имя файла, в котором хранятся имена групп и их членов. Его
формат: AuthUserFile имя
- задает имя файла с паролями. По большому счету для его формирования
надо воспользоваться утилитой htpasswd из поставки Apache. Но по крайней
мере для некоторых версий сервера этот формат такой: Passwordhash вполне можно получить
стандартной функцией Perl'а: Так что вполне можно автоматизировать процесс добавления новых пользователей, смену паролей через html-формы и т.д. require user user1 user2 и require group user1 user2 позволяют указать, какие пользователи и группы получат доступ к данному каталогу. require valid-user разрешает доступ всем пользователям, указанным в файле паролей системы. <Limit method1 method2 ...> ... </Limit> , где methodi определяет HTTP-метод. Например, <Limit GET POST> ограничивает применение вложенных в нее директив случаями использования методов GET и POST (обычно этого более чем достаточно). Вложенными могут быть директивы require, order, allow и deny. Еще пара полезных директив - deny и allow
- соответственно запрещения и разрешения доступа. Применяются примерно
так: По умолчанию сначала выполняются все deny, потом все allow, так что allow from all разрешит доступ всем пользователям, невзирая ни на какие deny. Порядок можно изменить директивой order: order allow, deny. deny from all отлично сочетается со вторым способом защиты страниц через CGI, именно этой директивой лучше всего прикрывать всякие пароли к гостевым книгам и т.д. При попытке обращения к страницам из этого каталога пользователь получит нечто такое. Кстати, тут между делом демонстрируется
самостоятельная обработка ошибок: в данном случае - код 403, Forbidden.
Аналогично обрабатывается и всеми любимая 404, Not Found, и 401, Unauthorized.
Для этого достаточно добавить в .htaccess директиву ErrorDocument
код url: Все, что делает скрипт - формирует сообщение об ошибке, используя переменную окружения REQUEST_URI, так что всместо него вполне можно просто указать какую-нибудь подходящую страницу. Для заключительного примера используем файл .htaccess со следующим содержимым: AuthType Basic
AuthName Test
AuthGroupFile /.../pagepsw/deny/tgroup
AuthUserFile /.../pagepsw/deny/tuser
<Limit GET POST>
require group test
</Limit>
В файле tgroup всего одна строчка - test: login test, в файле tuser - зашифрованные пароли для login (password) и test (test). Результат можете оценить здесь. Обратите внимание, при повторном обращении к этой странице броузер понимает, что только что обращался к этой области, и не утруждает пользователя лишним запросом пароля. Таков вкратце минимальный набор сведений, необходимых для защиты web-страниц. Как показывает практика, более-менее доверять стоит лишь решениям, основанным на средствах, предоставляемых сервером (и то до тех пор, пока в сервере не обнаружится очередная дырка), так что если есть возможность, лучше выбирать именно их. |
|
Web дизайн: Бурлаков Михаил
Web программирование: Бурлаков Михаил