Брандмауер та авторизація
Дата оновлення перекладу 2023-06-07
Брандмауер та авторизація
Основним елементом компонента Security є авторизація. Вона обробляється екземпляром AuthorizationCheckerInterface. Коли всі кроки аутентифікації користувача були пройдені успішно, ви можете запитати перевіряльника авторизації, чи має аутентифікований користувач доступ до певної дії або джерела додатка:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
// екземпляр Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
$tokenStorage = ...;
// екземпляр Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface
$authenticationManager = ...;
// екземпляр Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface
$accessDecisionManager = ...;
$authorizationChecker = new AuthorizationChecker(
$tokenStorage,
$authenticationManager,
$accessDecisionManager
);
// ... аутентифікувати користувача
if (!$authorizationChecker->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}
Note
Прочитайте відповідні розділи, щоб дізнатися більше про Аутентифікація та Авторизація.
Брандмауер для HTTP-запитів
Аутентифікація користувача проводиться брандмауером. Додаток може мати кілька безпечних областей, тому брандмауер конфігурується з використанням мапи цих областей. Для кожної з них мапа містить зіставник запитів і набір слухачів. Зіставник запитів надає брандмауеру можливість визначити, чи вказує поточний запит на безпечну область. Після цього слухачів запитують, чи може поточний запит бути використаний для аутентифікації користувача:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
use Symfony\Component\Security\Http\FirewallMap;
use Symfony\Component\HttpFoundation\RequestMatcher;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
$firewallMap = new FirewallMap();
$requestMatcher = new RequestMatcher('^/secured-area/');
// екземпляри Symfony\Component\Security\Http\Firewall\ListenerInterface
$listeners = array(...);
$exceptionListener = new ExceptionListener(...);
$firewallMap->add($requestMatcher, $listeners, $exceptionListener);
Мапа брандмауера буде передана брандмауеру в якості його першого аргументу, разом з диспетчером подій вона буде використана класом HttpKernel:
1 2 3 4 5 6 7 8 9 10 11 12
use Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpKernel\KernelEvents;
// EventDispatcher використовуваний HttpKernel
$dispatcher = ...;
$firewall = new Firewall($firewallMap, $dispatcher);
$dispatcher->addListener(
KernelEvents::REQUEST,
array($firewall, 'onKernelRequest')
);
Брандмауер реєструється для того, щоб слухати подію kernel.request
, яка буде
оголошена HttpKernel на початку кожного запиту, який він обробляє. Таким чином,
брандмауер може утримати користувача від переходу далі, ніж йому дозволено.
Конфігурація брандмауера
Інформація про заданий брандмауер, на кшталт імені, провайдера, контексту, точки входу та URL забороненого доступу, надається екземплярами класу FirewallConfig.
До цього обʼєкта можна отримати доступ через метод
getFirewallConfig(Request $request)
класу
FirewallMap і через метод
getConfig()
класу FirewallContext.
Слухачі брандмауера
Коли брандмауер отримує сповіщення про подію kernel.request
, він запитує
мапу брандмауера, чи збігається запит з однією з безпечних областей. Перша безпечна
область, яка збігається із запитом, поверне набір відповідних слухачів
брандмауера (кожен з яких реалізує
ListenerInterface). Ці
слухачі всі будуть обробляти поточний запит. Це насправді означає:
дізнайтеся, чи містить поточний запит будь-яку інформацію, за якою користувач
може бути аутентифікований (наприклад Базовий слухач аутентифікації HTTP перевіряє,
чи має запит заголовок під назвою PHP_AUTH_USER
).
Слухач виключень
Якщо будь-який зі слухачів викличе AuthenticationException, то слухач виключень, який був наданий при додаванні безпечних областей у мапу брандмауера, почне свою роботу.
Слухач виключень визначає, що станеться далі, ґрунтуючись на аргументах, який він отримав під час створення. Він може почати процедуру аутентифікації, можливо попросити користувача повторно надати особисті дані (якщо він був аутентифікований лише на засаді на куки "запам'ятати мене"), або перетворити виключення на AccessDeniedHttpException, яке в підсумку призведе до відповіді "HTTP/1.1 403: Відмова в доступі".
Точки входу
Якщо користувач взагалі не аутентифікований (тобто коли сховище токенів
ще не має жодного токена), точка входу брандмауера буде викликана для
"запуску" процесу аутентифікації. Точка входу повинна релізувати
AuthenticationEntryPointInterface,
який має тільки один метод: start().
Цей метод отримує поточний об'єкт Request
і виключення, за яким буде викликатися слухач виключень. Метод також
повинен повертати об'єкт Response.
Це може бути, наприклад, сторінка, що містить форму входу, або у випадку з базовою
HTTP аутеніфікацією, відповідь із заголовком WWW-Authenticate
, яка попросить
користувача надати ім'я та пароль.
Процес: Брандмауер, Аутентифікація, Авторизація
Сподіваємося, що тепер ви можете трохи побачити те, як іде "процес" у контексті безпеки:
- Брандмауер реєструється, як слухач події
kernel.request
; - На початку запиту, Брандмауер перевіряє мапу брандмауера, щоб побачити, чи потрібно активувати будь-який із брандмауерів для цього URL;
- Якщо в мапі для цього URL був знайдений брандмауер, то сповіщуються його слухачі;
- Кожен слухач перевіряє, чи містить поточний запит будь-яку інформацію
аутентифікації - слухач може (а) аутентифікувати користувача, (б)
викликати
AuthenticationException
, або (в) нічого не робити (оскільки в запиті немає жодної інформації аутентифікації); - Як тільки користувач буде аутентифікований, ви будете використовувати Авторизація, щоб відмовити в доступі до певних джерел.
Прочитайте наступні розділи, щоб дізнатися більше про Аутентифікація і Авторизація.