Двухуровневая авторизация в менеджере

Привет, друзья!

После прочтения этого и этого
Хочу поделиться двухуровневой авторизацией в менеджере с помощью Basic Authentication.
Мой вариант отличается от пользователя «Борода», тем что «Пользователь» и «Пароль» (в md5()) хранятся в БД.

Если интересно читаем далее…

1. Сначала нужно создать таблицу в БД MODX для хранения пользователя и пароля. Существует несколько способов. Я делал через Console:
$sql = "CREATE TABLE
    `modx_manager_access` (
        `user` VARCHAR(10) NOT NULL,
        `pwd` VARCHAR(32) NOT NULL,
        PRIMARY KEY(`user`)
    )";

$q = new xPDOCriteria($modx, $sql);
$q->prepare();
$q->stmt->execute();

Либо из phpmyadmin выполнить SQL запрос:
CREATE TABLE
    `modx_manager_access` (
        `user` VARCHAR(10) NOT NULL,
        `pwd` VARCHAR(32) NOT NULL,
        PRIMARY KEY(`user`)
    )
2. Добавляем пользователя и пароль.
В интернете существует сервис, позволяющий превратить значение в md5.
Через phpmyadmin это сделать просто. А вот вариант для Console:
$user = 'user'; //имя пользователя
$pwd  = 1; //пароль
$pwd  = md5($pwd); //пароль в md5()

$sql = "INSERT INTO modx_manager_access (user, pwd) VALUES (?, ?)";
$q = new xPDOCriteria($modx, $sql);
$q->prepare();
$q->bind( array(1 => $user, 2 => $pwd) );
$q->stmt->execute();
Пароль хранится в md5()
Можно выбрать и другой способ хранения, например SHA1() или как сам MODX хранит пароли в PBKDF2.
Примеров скрипта не приведу. Можно дописать самому.

3. Сам плагин. Вешаем его на событие OnManagerPageInit
switch ($modx->event->name) {
    case 'OnManagerPageInit':
        $user    = ''; //имя пользователя
        $pwd     = ''; //пароль
        $cancel  = 'Error!'; //сообщение при нажатии по кнопке "Отмена"
        $ip      = $_SERVER['REMOTE_ADDR']; // IP клиента
        $success = 'Попытка пройти Basic авторизацию!!!' . ' IP пользователя: ' . $ip; //сообщение в случае перебора связки имя/пароль (увидем в логе MODX)
        
        $sql = "SELECT user, pwd FROM `modx_manager_access`"; //запрос в БД
        $q = new xPDOCriteria($modx, $sql);
	//вытягиваем пользователя и пароль
        if ($q->prepare() && $q->stmt->execute()) {
        	$row  = $q->stmt->fetch(PDO::FETCH_ASSOC);
        	$pwd  = $row['pwd'];
        	$user = $row['user'];
        }
        
	//функция, которая будет выводится при не успешном вводе имени и пароля
        function authorization(){
            header('WWW-Authenticate: Basic');
            header('HTTP/1.0 401 Unauthorized');
            die($cancel);
        }
        
        if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])){
            authorization();
        }else{
            $auth_user = $_SERVER['PHP_AUTH_USER'];
            $auth_pass = $_SERVER['PHP_AUTH_PW'];
        }
        
        if ( !(isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER'] == $user && isset($_SERVER['PHP_AUTH_PW']) && md5($_SERVER['PHP_AUTH_PW']) == $pwd)) {
            $modx->log(1, $success);
            authorization();            
        }
    break;
}
Проверяем!
Я проверял в «режиме инкогнито» Chrome и в FF. Возможно придется почистить кэш браузера Вашего домена.



Переходим по site_name.com/manager/ (у Вас может отличаться)
Выскакивает окно авторизации Basic Authentication. Оно будет появляться до тех пор пока менеджер не введет «Имя Пользователя» — user и «Пароль» — 1 (в случае данного скрипта) или нажатие клавиши «Отмена»

Давай-те обмозгуем это моё скромное творчество!

Надо понять насколько эта авторизация безопасна, затем можно выделить это в отдельный компонент с изменением пользователя и пароля в админке.

P.S. код сырой — знаю.
t3mnikov
21 марта 2016, 11:34
modx.pro
6
5 671
+7

Комментарии: 20

Борода
21 марта 2016, 16:11
0
Есть ли смысл в этом, если это только для менеджера?) Она так же безопасна как и обычная авторизация) Просто процесс идёт два раза) Через .htpasswd закрываются все необходимые служебные папки)
    t3mnikov
    21 марта 2016, 16:24
    0
    Ок! Доделаю до компонента, выложу на gihub'e в виде пакета.
    Алексей
    21 марта 2016, 17:28
    0
    Было бы классно, если этот метод авторизировал сразу в админке.
      t3mnikov
      21 марта 2016, 19:08
      0
      Алексей, я думаю это не сложно. Скрипт позже скину. Но моей целью было двойная авторизация!
        @ndrew
        21 марта 2016, 21:45
        0
        Тогда в чем смысл двойной авторизации? Чем Вас не устраивает сразу авторизироваться в админке? ;)
          Алексей
          22 марта 2016, 09:36
          0
          Стандартная авторизация в админке раскрывает что сайт сделан на modx, и плюсом тут можно отдать заголовок 403 при неправильном пароле.
            Борода
            22 марта 2016, 13:13
            +3
            Ты хочешь спрятать от менеджера, что сайт на МОДЭКСе?) А внутри админки он не поймёт?) А если прятать от сторонних пользователей, то достаточно переименовать папку менеджер)
              t3mnikov
              22 марта 2016, 15:14
              0
              Можно (и нужно) сменить шаблон для входа в админку. =)
                Alexander V
                22 марта 2016, 18:03
                +3
                А еще можно менеджера в рабство взять, чтобы не разглашал.
                Boris Akimenko
                23 марта 2016, 19:17
                +1
                Это сделано для того чтобы прятать не от менеджера.
        Іван Клімчук
        23 марта 2016, 15:48
        +3
        А я уже понадеялся почитать про настоящую двухуровневую авторизация с смсками и токенами, а тут просто basic-авторизацию навесили. Эх…
          t3mnikov
          23 марта 2016, 19:09
          0
          Можно и смсками и токенами — это уже четырехуровневая авторизация будет! =))
            Сергей Шлоков
            24 марта 2016, 08:17
            0
            С токенами есть в AdminTools — вводишь логин и на почту получаешь ссылку для входа. Никакие переборы не страшны. Можно выпилить.
              Сергей Шлоков
              24 марта 2016, 08:43
              0
              Забыл сказать, ещё и папку админки не светишь.
              Василий Наумкин
              24 марта 2016, 07:44
              8
              +2
              Лично я закрываю служебные директории через веб-сервер на случай обнаружения новой уязвимости в MODX.

              Например, как это было, когда движок некорректно обрабатывал запросы в несуществующий контекст в коннекторах. Там еще одна PHP авторизация не помогла бы, так как хакер получал доступ к API через обычные GET запросы к определённому файлу.

              Именно поэтому я закрываю для доступа снаружи и админку, и коннекторы, и ядро. Причём, не через потенциально уязвимый движок, а средствами гораздо менее потенциально уязвимого Nginx.
              location ~* ^/(core|manager|connectors)/ {
                  auth_basic "Restricted Access";
                  auth_basic_user_file /home/site/.htpasswd;
                  try_files               $uri $uri/ @rewrite;
                  location ~ \.php$ {
                          include         fastcgi_params;
                          fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                          fastcgi_pass    backend-site;
                  }
              }

              А зачем нужна вот эта инструкция — большой вопрос.
                t3mnikov
                24 марта 2016, 08:03
                0
                Обезопасить вход в админку от зловредителей, и думаю Basic Auth невозможно перебирать брутом, пароль в БД в любом зашифрованом виде.
                  Василий Наумкин
                  24 марта 2016, 08:17
                  +2
                  Nginx закрывает директории тем же Basic Auth, если ты не в курсе.

                  Причем, закрыть можно доступ не только в админку, но и в другие служебные директории (не только файлы!), да еще и без создания таблиц в БД и вообще, использования PHP.

                  Какие преимущества у твоего более сложного и потенциально уязвимого метода? На мой взгляд — никаких.

                  Ссылочки для проверки:
                  modx.pro/manager/
                  modx.pro/core/
                  modx.pro/connectors/
                    Борода
                    24 марта 2016, 08:20
                    +1
                    Василий всё по делу расписал. Дополнительно обезопасить лучше средствами Nginx или Apache, чем навешивать дополнительные плагины на движок, в котором может быть уязвимость) Это тоже самое, что в дверь поставить два одинаковых замка, но с разными ключами)
                  t3mnikov
                  24 марта 2016, 08:45
                  1
                  0
                  Всем спасибо за дельные советы! )
                    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                    20