CakePHP : Manual11/Security

Компонент безопасности


Оглавление документа

Введение

Компонент безопасности используется для защиты действий вашего контроллера от злоумышленных и неподходящих запросов. Это позволяет вам устанавливать условия, только при выполнении которых можно будет запросить действие, и опционально определить что делать с запросами, которые не удовлетворяют условия. Опять-таки, перед использованием компонента безопасности, вы должны убедиться что 'Security' добавлен в массив $components вашего контроллера.

Защита действий контроллера

Компонент безопасности содержит два основных метода для распределения доступа к действиям контроллера:

requirePost

Для выполнения определенного действия, нужно чтобы оно было запрошено через POST.

requireAuth

Убеждается, что запрос пришел из пределов приложения, проверяя ключ аутентификаци в данных отправленых POST, сравнивая его с ключом аутентификации сохраненной в сессии пользователя. Если они соответствуют, то действию разрешено выполняться. Имейте ввиду, по причине гибкости, эта проверка запускается только если данные формы были отправлены методом POST. Если же действие вызывается регулярным запросом GET, requireAuth() не будет ничего делать. Для максимальной безопасности вам стоит использовать requirePost() и requireAuth() на действиях, которые вы хотите полностью защитить. Подробнее о том, как генерируется ключ аутентификации в Разделе 4 ниже.

Но сначала давайте взглянем на простой пример:
<?
class ThingsController extends AppController
{
    var 
$components = array('Security');

    function 
beforeFilter()
    {
        
$this->Security->requirePost('delete');
    }

    function 
delete($id)
    {
        
// Это будет происходить только если действие вызвано через POST
        
$this->Thing->del($id);
    }
}
?>


Здесь мы говорим компоненту безопасности, что действие 'delete' требует запроса POST. Метод beforeFilter() обычно там где вы хотите сообщить Security (и большинству других компонентов) что делать с самим собой. Он тогда будет делать что сказано сразу после того, как вызван beforeFilter(), но сразу перед тем как вызвано само действие.

Вы можете протестировать это, введя ссылку для действия в браузер и увидете, что произойдет.

Управление недействительными запросами

Что ж, если запрос не соответствует требованиям, которые мы определили, что с ним происходит? По умолчанию, запрос пропадает (black-holed), что значит, что клиенту посылается ошибка 404, а приложение сразу же завершает свою работу. Однако, у компонента безопасности есть свойство $blackHoleCallback, в котором вы можете вписать имя своей функции колбека, определенной в вашем контроллере.

Вместо того, чтобы просто выдавать ошибку 404 и потом ничего, это свойство позволяет вам выполнять какие-нибудь дополнительные проверки запроса, переадресовывать запрос в другое мето, или даже записать в лог IP адрес грешащего клиента. Однако, если вы выберете свой колбек, выход из приложения в случае недействительного запроса ложится на вашу совесть. Если ваш колбек возвращает true, тогда компонет безопасности продолжит проверять запрос по другим определенным требованиям. Иначе, проверка останавливается, а ваше приложение продолжает свободно работать.

Продвинутый запрос аутентификации

Метод requireAuth() позволяет вам дать максимум деталей при определении как и откуда будет получен доступ к действию, но это происходит с использованием обуславливания, которое становится более ясным, когда вы понимаете как этот метод аутентификации работает. Как начато уже выше, requireAuth() работает сравнением ключа аутентификации в данных POST с ключем, хранящимся в данных сессии пользователя. Поэтому, компонент безопасности должен быть включен как в контроллер принимающий запросы, так и в контроллер делающий запросы.

Например, если у меня есть действие в Posts Controller, которое отображает содержимое формы, переданное методом POST, в действии в Comments Controller, тогда компонент безопасности должен быть включен и в Comments Controller (который принимает запросы, и в общем-то защищает действие), и в Posts Controller (откуда поступают запросы).

Все время компонент безопасности загружен, даже если он не используется для защиты действий, он делает следующие вещи: сначала, он генерирует ключи аутентификации, используя основной класс Security. Потом, он пишет эти ключи в сессии, вместе с датой окончания действия ключа и некоторой дополнительной информацией (срок действия определяется вашими настройками безопасности сессий в /app/config/core.php). Далее, устанавливает ключ в вашем контроллере, с которым свяжутся позже.

Затем в ваших файлах отображения, любой тег формы, который вы генерируете используя $html->formTag() будет также содержать невидимое поле с ключем аутентификации. Таким образом, когда из формы данные отправляются (метод POST), компонент безопасности может сравнить это значение со значением в сессии. После этого, ключ аутентификации регенерируется, а сессия обновляется для следующего запроса.