Я нахожусь в процессе обновления Symfony с 2.8 до 3.4, и у меня есть прослушиватель аутентификации.
Конструктор слушателя
public function __construct(EntityManager $entityManager, SessionInterface $session, Security $security, LoggerInterface $logger, Redis $redis, $secret)
{
$this->entityManager = $entityManager;
$this->session = $session;
$this->security = $security;
$this->logger = $logger;
$this->redis = $redis;
$this->secret = $secret;
}
Функция по запросу, которая вызывает слушателя
public function onRequest(GetResponseEvent $event)
{
//Validate token
//Get Authorization Header
$headers = $event->getRequest()->headers;
$authHeader = $headers->get('Authorization');
//Check if Header value starts with 'Bearer'
if ($this->startsWith($authHeader, self::$BEARER_HEADER)) {
// Allow request to be processed by controllers
//token handler
} else {
$securityContext = $this->security;
if ($securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) {
return;
} else {
throw new SessionTimeoutException();
}
}
}
Service.yml
app.token_listener:
class: Insead\MIMBundle\Listener\AuthTokenListener
arguments: ["@doctrine.orm.entity_manager", "@session", "@security.helper", "@logger", "@redis.authtoken", "%secret%"]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequest, priority: 0 }
Запись списка ACL — security.php
'access_control' => array(
array('path' => '^/api/(.*?)/login', 'role'=>'IS_AUTHENTICATED_ANONYMOUSLY'),
)
я пытаюсь получить доступ к маршруту входа с именем пользователя и паролем, но я получаю следующую ошибку
GENERAL EXCEPTION: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. in
/var/www/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php line 55
Exception caught by Listener::
[
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Security.php",
"line": 65,
"function": "isGranted",
"class": "Symfony\\Component\\Security\\Core\\Authorization\\AuthorizationChecker",
"type": "->",
"args": [
"IS_AUTHENTICATED_ANONYMOUSLY",
null
]
},
{
"file": "/var/www/src/Insead/MIMBundle/Listener/AuthTokenListener.php",
"line": 135,
"function": "isGranted",
"class": "Symfony\\Component\\Security\\Core\\Security",
"type": "->",
"args": [
"IS_AUTHENTICATED_ANONYMOUSLY"
]
},
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php",
"line": 212,
"function": "onRequest",
"class": "Insead\\MIMBundle\\Listener\\AuthTokenListener",
"type": "->",
"args": [
null,
"kernel.request",
null
]
},
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php",
"line": 44,
"function": "doDispatch",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"args": [
[
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onRequest"
],
[
null,
"onController"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"configure"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onKernelRequest"
],
[
null,
"onRequest"
]
],
"kernel.request",
null
]
},
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php",
"line": 127,
"function": "dispatch",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"args": [
"kernel.request",
null
]
},
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php",
"line": 68,
"function": "handleRaw",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"args": [
{
"attributes": null,
"request": null,
"query": null,
"server": null,
"files": null,
"cookies": null,
"headers": null
},
1
]
},
{
"file": "/var/www/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php",
"line": 200,
"function": "handle",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"args": [
{
"attributes": null,
"request": null,
"query": null,
"server": null,
"files": null,
"cookies": null,
"headers": null
},
1,
true
]
},
{
"file": "/var/www/web/app.php",
"line": 29,
"function": "handle",
"class": "Symfony\\Component\\HttpKernel\\Kernel",
"type": "->",
"args": [
{
"attributes": null,
"request": null,
"query": null,
"server": null,
"files": null,
"cookies": null,
"headers": null
}
]
}
]
Я потратил дни на это, и я до сих пор не мог понять, как это исправить.
Прошу прощения, если на этот вопрос уже дан ответ, я пытался найти и пробовал вещи, которые упоминались в разных сообщениях, и это не решило проблему. Я тоже новичок в symfony.
Полная безопасность.php
https://www.codepile.net/pile/7O1LJkpv
AuthTokenListner.php
Это похоже на то, что ваш слушатель вызывается перед прослушивателем аутентификации. Используйте «bin/console debug:event-dispatcher kernel.request», чтобы убедиться, что ничего странного не происходит. Я предполагаю, что вам может понадобиться использовать $security->getToken(), чтобы убедиться, что у вас есть токен, но на самом деле вам это не нужно. И обязательно закомментируйте раздел управления доступом в security.yaml. Если это «решает» проблему, добавляйте по одному правилу за раз, чтобы изолировать фактическую проблему.
@BoShurik Спасибо за ответ. пожалуйста, проверьте security.php по этой ссылке codepile.net/pile/7O1LJkpv
@Эльнур Абдуррахимов Пожалуйста, разберитесь с этой проблемой. Я сделал все, что мог. Но я не мог решить эту проблему.
@nifr Пожалуйста, разберитесь с этой проблемой. Я сделал все, что мог. Но я не мог решить эту проблему
@Cerad Пожалуйста, разберитесь с этой проблемой. Я сделал все, что мог. Но я не мог решить эту проблему
if (!$securityContext->getToken() || $securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) {
, вероятно, сработает, но это всего лишь обходной путь. Настоящая проблема прячется где-то в другом месте
Может быть, у вас есть render(controller())
звонки на странице входа, так что if (!$event->isMasterRequest()) return;
поможет
Я считаю, что это контекст безопасности, который устарел/удален. isGranted необходимо вызывать в средстве проверки авторизации
return $this->get('security.authorization_checker');
Вам нужен сервис security.authorization_checker.
Затем вы вызываете isGranted в сервисе author_checker.
// get the service from the container or pass it in via injection
$authChecker = $this->get('security.authorization_checker');
if ($authChecker->isGranted('IS...')) { ... }
Я использовал ректора для более легкой миграции. Я настоятельно рекомендую https://github.com/rectorphp/rector для плавной миграции. Я могу гарантировать, что вы сэкономите много времени, используя этот инструмент.
https://www.tomasvotruba.cz/blog/2019/02/28/how-to-upgrade-symfony-2-8-to-3-4/
вы имеете в виду изменение $securityContext = $this->security; if ($securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) { return; } else { бросить новое исключение SessionTimeoutException(); } вернуть $this->get('security.authorization_checker'); ?
@ThilinaDinithFonseka Нет, проверь мой ответ
@Pie Несколько новый класс Security включает в себя предлагаемые вами функции.
Привет @Pie, я сделал, как ты сказал, но опять же я получил ту же ошибку, сделал это точно так же, как Дилан Кас, упомянутый ниже
@Pie Извините, что такое оба решения? Ваше решение, упомянутое выше, и решение Дилана совпадают, верно?
Введите Проверка авторизации в свой класс
protected $authChecker;
public function __construct(AuthorizationChecker $authChecker)
{
$this->authChecker = $authChecker;
}
Внедрив его в свой service.yml
XXXXXXXXX:
class: App\XXX\XXXX\XXXXX
arguments: [ "@security.authorization_checker" ]
А затем используйте его для проверки роли с помощью isGranted
if ($this->authChecker->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) {
}
Класс Security оборачивает функциональность isGranted.
@dylan спасибо за ответ. Я сделал именно то, что вы указали выше, и все равно получаю ту же ошибку.
@Cerad увидел, что вы упомянули тот же комментарий выше. что ты имеешь ввиду? не могли бы вы объяснить больше?
Проблема была с порядком приоритета.
спасибо @cerad за подсказку об этом
bin/console debug:event-dispatcher kernel.request
помог решить вопрос. я использовал
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse, priority: 10 }
в Services.yml, и у него был конфликт с
getSubscribedEvents()
поэтому я удалил теги и оставил только
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array('onKernelRequest', 10),
);
}
затем я переместил прослушиватель аутентификации вниз, предоставив высокий приоритет двум другим слушателям, как это было в symfony 2.8.
Спасибо всем за помощь в этом, особенно @Pie @Cerad и @BoShurik
Можете ли вы поделиться всей конфигурацией безопасности? Похоже, вы пытались проверить роль на странице, которая не контролируется брандмауэром. (например, шаблон вашего брандмауэра —
/api
, но вы проверяете разрешения на/
)