Symfony Как узнать авторизован ли юзер в другом firewall

noneim

Новичок
В symfony создаю 2 провайдера и 2 правила firewall:
providers:
# Провайдер 1 - используем для админки, доступа к тестам и т.п.
in_memory:
memory:
users:
admin: { password: password1111, roles: [ 'ROLE_ADMIN' ] }
# Провайдер 2 - используем сервис rhuser_provider - для клиентов.
webservice:
id: rhuser_provider

И соответственно 2 правила firewall:
firewalls:
# Без аутентификации к профайлеру, картинкам и скриптам.
dev:
......
# Провайдер 1 - авторизация по форме, доступ к админке (тесты и т.п.)
adminarea:
pattern: /admin/.*
provider: in_memory
.........................
# Провайдер 2 - авторизация по форме (для клиентов)
clientarea:
pattern: ^/
provider: webservice

___________________________________________________________________________

Теперь по адресу /admin может быть залогинен админ, по адресу / может быть залогинен обычный юзер, причем одновременно эти 2 юзера могут быть залогинены. Теперь вопрос, как узнать в обычных контроллерах сайта залогинен ли админ? Т.е. задача такая - отображать админскую панель на всех страницах сайта (если админ залогиен), но при этом не путать этих 2-х юзеров.

Т.е. возожны 3 состояния:
1) админ и клиент не залогинены
2) админ залогинен, клиент нет - отображаются кнопки редактирования сайта для админа
3) админ не залогинен, клиент залогинен - кнопок редактирования контента для админа нет
4) админ залогинен, клиент залогинен - доступны как клиентские скрытые разделы, так и админские
 

Sender

Новичок
посмотри Symfony\Component\Security\Http\Firewall\ContextListener, вот сюда обрати внимание:
if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) {

Это то что тебе надо. Остальное откопаешь исходя из этой информации.
 

noneim

Новичок
Спасибо, работает:
if (null !== $session && ($token = $session->get('_security_app1') ) ) {
$token = unserialize($token);
$roles = $token->getRoles();
foreach ($roles as $role) {
echo "ROLE: " . $role->getRole() . "<br>"; // ROLE_ADMIN need
}
}
Но выглядит это конечно немного костыльно, надеюсь в будущем не поломают функционал
 

Sender

Новичок
Ну мне кажется немного желание костыльное. Насколько я понимаю symfony работает только с одним токеном. Лучше все это решать через стандартный isGranted как-нибудь.

то что в сессии есть этот токен, это не гарантирует что этот токен был авторизован. Надо глубоко там разбираться
 

noneim

Новичок
Почему же желание авторизации нескольких разных юзеров костыльное? Для примера - есть несколько типов клиентов, которые имеют доступ к разным разделам сайта, или же одна и та же страница в зависимости от типа залогиненного клиента может иметь разный вид. При этом назначать админские права обычным клиентам нежелательно. При этом, если админ залогинен, появляется панелька для редактирования различных текстовых блоков на страницах сайта, в том числе кнопка на переключение на любого клиента, зарегистрированного в системе - думаю это гораздо удобнее, чем делать флаг isAdmin у клиентских аккаунтов.
 

Sender

Новичок
> Почему же желание авторизации нескольких разных юзеров костыльное
Потому что Controller->getUser например возвращает одного юзера. В сессии то у тебя все равно будет один юзер. А ты хочешь двух, отсюда у тебя начинаются пляски с этими файерволами.

> При этом назначать админские права обычным клиентам нежелательно
Почему нежелательно? Юзер не может быть админом?
 

noneim

Новичок
Юзер не может быть админом?
Юзеры авторизуются по api, в том числе по этому же api же api передается другая инфа - заказы, текущие настройки юзера, продукты и т.п. Т.к. апи система не моя, то не могу ей доверить чтобы когото из юзеров назначить админом. Если намешать авторизацию и локально - то не будет доступа к апи методам, нужным клиенту. Таким образом, в данном моем случае, админ - это вообще отдельная сущность, не связанная с клиентами.
 

Sender

Новичок
Юзеры авторизуются по api, в том числе по этому же api же api передается другая инфа - заказы, текущие настройки юзера, продукты и т.п. Т.к. апи система не моя, то не могу ей доверить чтобы когото из юзеров назначить админом. Если намешать авторизацию и локально - то не будет доступа к апи методам, нужным клиенту. Таким образом, в данном моем случае, админ - это вообще отдельная сущность, не связанная с клиентами.
Я бы решал это на уровне провайдера. Тебе все равно надо контроллировать чтобы тебе API нежелательную роль не инжектила. Там же можно искать пересечение клиента и твоей базы админов, и если пересечение есть, то добавлять роль админа. Тебе надо просто связку админ-юзер сделать, причем храниться это будет в админе. Это намного лучше, чем пытаться работать с двумя пользователеми одновременно. Там ты наловишь проблем.
 

noneim

Новичок
Пример - допустим сайт, где могут быть зареганы покупатели и продавцы, ок, в раздел /customers будут допущены только покупатели, в раздел /salers только продавцы. Теперь в разделе / на главной можно будет писать так: Продавец: залогинен Покупатель: (не) залогинен. Это имеет смысл, т.к. продавец может иметь несколько аккаунтов покупателя, и хотеть перезалогиниться каким-нибудь покупателем, при этом не разлогинившись в качестве продавца. Но на главной конечно должна быть инфа - что вот и под тем и под тем залогинено, что невозможно, если иметь доступ только к одному токену.
 
Последнее редактирование:

Sender

Новичок
то что ты хочешь, это все можно реализовать в принципе

Разве что тебе надо будет isGranted свой запилить, который будет бегать по всем токенам. Стандартный isGranted тут не прокатит, он только один токен смотрит.
 
Сверху