2010-10-19 12:06:43 +01:00
< ? php
2011-01-15 13:29:43 +00:00
/*
* This file is part of the Symfony package .
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2011-01-15 13:29:43 +00:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2011-01-26 20:34:11 +00:00
namespace Symfony\Component\Security\Http ;
2010-10-19 12:06:43 +01:00
2011-03-13 18:16:56 +00:00
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
2012-11-06 10:06:32 +00:00
use Symfony\Component\EventDispatcher\EventSubscriberInterface ;
2018-07-26 10:03:18 +01:00
use Symfony\Component\HttpKernel\Event\FinishRequestEvent ;
use Symfony\Component\HttpKernel\Event\GetResponseEvent ;
2019-03-22 06:07:54 +00:00
use Symfony\Component\HttpKernel\Event\RequestEvent ;
2018-07-26 10:03:18 +01:00
use Symfony\Component\HttpKernel\KernelEvents ;
2018-08-01 15:08:30 +01:00
use Symfony\Component\Security\Http\Firewall\AccessListener ;
2018-05-17 17:15:49 +01:00
use Symfony\Component\Security\Http\Firewall\LogoutListener ;
2010-10-19 12:06:43 +01:00
/**
2010-10-23 09:42:49 +01:00
* Firewall uses a FirewallMap to register security listeners for the given
* request .
2010-10-19 12:06:43 +01:00
*
* It allows for different security strategies within the same application
2010-10-23 09:42:49 +01:00
* ( a Basic authentication for the / api , and a web based authentication for
* everything else for instance ) .
2010-10-19 12:06:43 +01:00
*
2011-03-06 11:40:06 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2010-10-19 12:06:43 +01:00
*/
2012-11-06 10:06:32 +00:00
class Firewall implements EventSubscriberInterface
2010-10-19 12:06:43 +01:00
{
2011-03-07 17:17:46 +00:00
private $map ;
2011-03-13 18:16:56 +00:00
private $dispatcher ;
2013-09-08 14:07:37 +01:00
private $exceptionListeners ;
2010-10-19 12:06:43 +01:00
2011-03-13 18:16:56 +00:00
public function __construct ( FirewallMapInterface $map , EventDispatcherInterface $dispatcher )
2010-10-19 12:06:43 +01:00
{
$this -> map = $map ;
2011-03-13 18:16:56 +00:00
$this -> dispatcher = $dispatcher ;
2013-09-08 14:07:37 +01:00
$this -> exceptionListeners = new \SplObjectStorage ();
2010-10-19 12:06:43 +01:00
}
2018-10-18 21:44:28 +01:00
/**
* @ internal since Symfony 4.3
*/
2011-06-21 15:34:33 +01:00
public function onKernelRequest ( GetResponseEvent $event )
2010-10-19 12:06:43 +01:00
{
2013-08-08 22:41:21 +01:00
if ( ! $event -> isMasterRequest ()) {
2010-10-19 12:06:43 +01:00
return ;
}
2010-12-03 17:47:54 +00:00
// register listeners for this firewall
2018-05-11 19:46:08 +01:00
$listeners = $this -> map -> getListeners ( $event -> getRequest ());
2018-05-17 17:15:49 +01:00
if ( 3 !== \count ( $listeners )) {
@ trigger_error ( sprintf ( 'Not returning an array of 3 elements from %s::getListeners() is deprecated since Symfony 4.2, the 3rd element must be an instance of %s or null.' , FirewallMapInterface :: class , LogoutListener :: class ), E_USER_DEPRECATED );
$listeners [ 2 ] = null ;
}
2018-08-18 21:38:48 +01:00
$authenticationListeners = $listeners [ 0 ];
$exceptionListener = $listeners [ 1 ];
2018-08-19 09:17:45 +01:00
$logoutListener = $listeners [ 2 ];
2018-08-01 15:08:30 +01:00
2018-08-18 21:38:48 +01:00
if ( null !== $exceptionListener ) {
2014-03-09 11:57:49 +00:00
$this -> exceptionListeners [ $event -> getRequest ()] = $exceptionListener ;
$exceptionListener -> register ( $this -> dispatcher );
2010-10-19 12:06:43 +01:00
}
2018-08-18 21:38:48 +01:00
$authenticationListeners = function () use ( $authenticationListeners , $logoutListener ) {
$accessListener = null ;
2018-05-11 19:46:08 +01:00
2018-08-18 21:38:48 +01:00
foreach ( $authenticationListeners as $listener ) {
if ( $listener instanceof AccessListener ) {
$accessListener = $listener ;
continue ;
}
yield $listener ;
}
if ( null !== $logoutListener ) {
yield $logoutListener ;
}
if ( null !== $accessListener ) {
yield $accessListener ;
}
};
2018-08-18 17:47:20 +01:00
2018-10-18 21:44:28 +01:00
if ( $event instanceof RequestEvent ) {
$this -> callListeners ( $event , $authenticationListeners ());
} else {
$this -> handleRequest ( $event , $authenticationListeners ());
}
2010-10-19 12:06:43 +01:00
}
2012-11-06 10:06:32 +00:00
2018-10-18 21:44:28 +01:00
/**
* @ internal since Symfony 4.3
*/
2013-09-08 14:07:37 +01:00
public function onKernelFinishRequest ( FinishRequestEvent $event )
{
$request = $event -> getRequest ();
if ( isset ( $this -> exceptionListeners [ $request ])) {
$this -> exceptionListeners [ $request ] -> unregister ( $this -> dispatcher );
unset ( $this -> exceptionListeners [ $request ]);
}
}
2013-08-21 23:25:28 +01:00
/**
2014-04-15 06:57:34 +01:00
* { @ inheritdoc }
2013-08-21 23:25:28 +01:00
*/
2012-11-06 10:06:32 +00:00
public static function getSubscribedEvents ()
{
2019-01-16 09:39:14 +00:00
return [
KernelEvents :: REQUEST => [ 'onKernelRequest' , 8 ],
2013-09-08 14:07:37 +01:00
KernelEvents :: FINISH_REQUEST => 'onKernelFinishRequest' ,
2019-01-16 09:39:14 +00:00
];
2012-11-06 10:06:32 +00:00
}
2017-06-02 15:08:16 +01:00
2018-10-18 21:44:28 +01:00
protected function callListeners ( RequestEvent $event , iterable $listeners )
{
$this -> handleRequest ( $event , $listeners );
}
/**
* @ deprecated since Symfony 4.3 , use callListeners instead
*/
2017-06-02 15:08:16 +01:00
protected function handleRequest ( GetResponseEvent $event , $listeners )
{
foreach ( $listeners as $listener ) {
2018-10-18 21:44:28 +01:00
if ( \is_callable ( $listener )) {
$listener ( $event );
} else {
@ trigger_error ( sprintf ( 'Calling the "%s::handle()" method from the firewall is deprecated since Symfony 4.3, implement "__invoke()" instead.' , \get_class ( $this )), E_USER_DEPRECATED );
$listener -> handle ( $event );
}
2017-06-02 15:08:16 +01:00
if ( $event -> hasResponse ()) {
break ;
}
}
}
2010-10-19 12:06:43 +01:00
}