基本上,您有三个选择:
1。创建自定义身份验证提供程序
如果你想真正监听防火墙,你需要创建一个自定义的身份验证提供程序,这是一项相当具有挑战性的任务。
您可以按照文档中的指南进行操作:http://symfony.com/doc/current/security/custom_authentication_provider.html
或http://sirprize.me/scribble/under-the-hood-of-symfony-security/
这里的重点是创建您自己的防火墙监听器,它决定是否对用户进行身份验证。一个防火墙可以有多个监听器。
2。倾听每个请求
或者,您可以监听kernel.request 事件,可能手动检查您是否在安全路径上,如果是,则通过辅助方法手动验证用户。示例:
namespace AppBundle\Subscriber;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class RequestSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $eventDispatcher;
public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher)
{
$this->tokenStorage = $tokenStorage;
$this->eventDispatcher = $eventDispatcher;
}
public static function getSubscribedEvents()
{
return [ KernelEvents::REQUEST => 'onRequest' ];
}
public function onRequest(GetResponseEvent $event)
{
// only master requests and not authenticated users
if (!$event->isMasterRequest() || $this->isUserLoggedIn()) {
return;
}
// add your own logic for creating or loading a User object
// and filtering secured routes
/* ... */
// wohoo, user is going to be logged in manually!
$this->authenticate($user, $event->getRequest(), 'secured_area');
}
protected function authenticate(UserInterface $user, Request $request, String $provider) : Bool
{
// password doesn't matter in this case
$token = new UsernamePasswordToken($user, null, $provider, $user->getRoles());
// actual authenticating
$this->tokenStorage->setToken($token);
// dispatch the authentication event, so event listeners can do stuff
$loggedUser = $token->getUser();
if ($loggedUser instanceof UserInterface && $loggedUser->isAccountNonLocked() &&
$loggedUser->isEnabled()) {
$this->eventDispatcher
->dispatch(
SecurityEvents::INTERACTIVE_LOGIN,
new InteractiveLoginEvent($request, $token)
);
return true;
}
return false;
}
protected function isUserLoggedIn()
{
$token = $this->tokenStorage->getToken();
if (!$token) {
return false;
}
return ($token->getUser() instanceof UserInterface);
}
}
别忘了将其添加到 app/config/services.yml:
app.request_subscriber:
class: AppBundle\Subscriber\RequestSubscriber
tags:
- { name: kernel.event_subscriber }
arguments: ['@security.token_storage', '@event_dispatcher']
3。关闭授权
(可能对你来说不是一个解决方案,因为你想验证,而不是授权用户,但我仍然为其他人提。)
在app/config/security.yml中,更改访问控制设置,让每个人都可以访问安全区域:
# ...
access_control:
- { path: ^/secured-area$, role: IS_AUTHENTICATED_ANONYMOUSLY }