我希望在成功验证后采取一些行动。
我创建了一个扩展的DefaultAuthenticationSuccessHandler类,并重新定义了onAuthenticationSuccess函数。
虽然身份验证成功,但程序从不进入功能:为什么?
namespace my_name_space;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Bridge\Monolog\Logger;
class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler {
private $em;
private $logger;
function __construct(Logger $logger, HttpUtils $httpUtils, EntityManager $em) {
parent::__construct($httpUtils);
$this->em = $em;
$this->logger = $logger;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
$this->logger->info("onAuthenticationSuccess");
$response = parent::onAuthenticationSuccess($request, $token);
$token->eraseCredentials();
$token->getUser()->addRole('ROLE_USER');
return $response;
}
}
services:
security.authentication.success.handler:
class: MY\NAMESPACE\AuthenticationSuccessHandler
arguments: ["@monolog.logger.php","@security.http_utils", "@doctrine.orm.default_entity_manager"]
security.yml
form_login:
check_path: _security_check
use_referer: true
use_forward: true
login_path: my_login
success_handler: security.authentication.success.handler
答案 0 :(得分:3)
您可以通过向相关安全标记注册服务来侦听成功登录尝试后触发的事件:
app.login_listener:
class: AppBundle\EventListener\LoginListener
arguments:
- @security.authorization_checker
- @security.token_storage
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: yourMethod }
yourMethod 可以包含您要执行的代码。
答案 1 :(得分:0)
SO,github,google groups上存在很多相同的问题,其中大多数都未解决。
此外,您应该定义自定义fireDate
,而不是扩展默认值。
示例:
<强> services.yml 强>
AuthenticationSuccessHandler
<强> CustomAuthenticationSuccessHandler.php 强>
login_success_handler:
class: YourBundle\EventListener\CustomAuthenticationSuccessHandler
arguments: ["@doctrine", "@router"]
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
不需要在表单中手动设置use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Routing\RouterInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Doctrine\ORM\EntityManager;
class CustomAuthenticationSuccessHandler {
private $em;
private $logger;
public function __construct(EntityManager $em, RouterInterface $router)
{
$this->em = $em;
$this->router = $router;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$this->onAuthenticationSuccess($event->getRequest(), $event->getAuthenticationToken());
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$user = $token->getUser();
$user->eraseCredentials();
$user->addRole('ROLE_USER');
$this->em->flush() // If you don't do this, your changes will not be saved.
$response = new RedirectResponse($this->router->generate('your_success_route'));
return $response;
}
}
,因为success_handler
是SuccessHandler
并将用于相应的事件。
答案 2 :(得分:0)
我不知道这里提出的交互式登录事件是什么,因此我写了一个单独的答案。 @chalasr 的回答对我有用,但有 security.authentication.success 事件:
login_success_handler:
class: YourBundle\EventListener\CustomAuthenticationSuccessHandler
arguments: ["@doctrine", "@router"]
tags:
- { name: kernel.event_listener, event: security.authentication.success, method: onAuthenticationSuccess }