Обрабатывать многоуровневые роли
У меня есть несколько приложений, которые работают с аутентифицированными пользователями.
Все эти приложения могут быть развернуты вместе для разных клиентов, но с одной и той же пользовательской базой данных.
Например сеть отелей.
Информация о ролях пользователя доступна в заголовке каждого запроса.
Например, менеджер имеет полный доступ в своем отеле, но доступ только для чтения в другом отеле.
Пример:
{
["organization":"paris","roles":[ADMIN,ROOT]],
["organization":"london","roles":[READ]]
}
Как я могу справиться со многими уровнями ролей в организациях?
В symfony я прочитал некоторую документацию об избирателях и ролях, но ничего о ролях в какой-то группе.
2 ответа
Избиратель путь
// src/Security/PostVoter.php
namespace App\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class OrganisationVoter extends Voter
{
// these strings are just invented: you can use anything
const READ= 'READ';
const EDIT = 'EDIT ';
protected function supports($attribute, $subject); bool //todo
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
// [...] check class like documentation
$organisation= $subject;
switch ($attribute) {
case self::READ:
return $this->canView($organisation, $user);
case self::EDIT:
return $this->canEdit($organisation, $user);
}
}
private function canView(Organisation $organisation, User $user)
{
//here your logic if your user has the same organisation
}
private function canEdit(Organisation $organisation, User $user)
{
//here your logic if your user has the same organisation than the one in parameter and the good level of right (admin, root)
}
}
Тогда в вашем контроллере (или веточку или где угодно)
if ($this->security->isGranted(OrganisationVoter::EDIT, $organisation)) {
return true;
}
То, что вы описываете, имеет "контроль доступа на основе атрибутов", написанный во всем. abac помогает вам экстернализировать / отделить авторизацию от приложения / API, которое вы хотите защитить. Это означает, что вы можете разрабатывать функциональность независимо от логики авторизации.
Существует несколько стандартов - а именно XACML и ALFA (сокращенный язык для авторизации).
Вот как выглядит архитектура:
- Точка реализации политики (PEP) перехватывает бизнес-поток и создает запрос авторизации, который отправляет на PDP
- Точка принятия решения о политике (PDP) оценивает входящий запрос на соответствие политикам, с которыми он настроен. Это в конечном итоге возвращает решение PEP
- PDP может использовать информационные точки политики (PIP) для извлечения недостающих метаданных (отдел пользователя, роль, местоположение; отдел ресурса, владелец...)
Предыдущий ответ заставляет вас реализовать избирателя. Это очень хрупко и требует регулярного кодирования и обновления по мере изменения ваших требований. В ALFA вам не нужно этого делать. Вы просто пишете политики на простом старом английском языке, которые используют интересующие вас атрибуты. Например:
- Пользователь с ролью == "менеджер" может выполнить действие == "просмотр" объекта типа == "гостиница"
- Пользователь с ролью == "менеджер" может выполнить действие == "изменить" на объекте типа == "гостиница", если hotel.owner == user.name