From aaf25253371abbeaf25a83192b264f65728476b0 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 21 Feb 2011 23:33:39 +0100 Subject: [PATCH] [Security][SecurityBundle] Handle subrequests in firewall. All firewall listeners are disconnected on core.request of the subrequest. The new listeners are then registered. As the last step of core.response of the subrequest all of the firewall listeners are unregistered and the firewall listeners of the super request are reconnected to allow them to handle events occuring later in the request processing (e.g. their own matching core.response). --- .../Resources/config/security.xml | 3 +- .../Component/Security/Http/Firewall.php | 32 ++++++++++++++++--- .../AbstractAuthenticationListener.php | 7 ++++ .../AbstractPreAuthenticatedListener.php | 7 ++++ .../Security/Http/Firewall/AccessListener.php | 9 +++++- .../AnonymousAuthenticationListener.php | 7 ++++ .../Firewall/BasicAuthenticationListener.php | 7 ++++ .../Http/Firewall/ChannelListener.php | 7 ++++ .../Http/Firewall/ContextListener.php | 8 +++++ .../Firewall/DigestAuthenticationListener.php | 7 ++++ .../Http/Firewall/ExceptionListener.php | 8 +++++ .../Http/Firewall/ListenerInterface.php | 13 +++++++- .../Security/Http/Firewall/LogoutListener.php | 7 ++++ .../Http/Firewall/RememberMeListener.php | 8 +++++ .../Http/Firewall/SwitchUserListener.php | 7 ++++ 15 files changed, 130 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index c0c90439e1767..9a8df9416f105 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -71,7 +71,7 @@ - + @@ -107,6 +107,7 @@ + diff --git a/src/Symfony/Component/Security/Http/Firewall.php b/src/Symfony/Component/Security/Http/Firewall.php index f7fabbba43945..25f6d88b253a9 100644 --- a/src/Symfony/Component/Security/Http/Firewall.php +++ b/src/Symfony/Component/Security/Http/Firewall.php @@ -34,6 +34,7 @@ class Firewall protected $map; protected $dispatcher; protected $currentListeners; + protected $listenersStack; /** * Constructor. @@ -54,16 +55,14 @@ public function __construct(FirewallMapInterface $map, EventDispatcherInterface */ public function handle(EventInterface $event) { - if (HttpKernelInterface::MASTER_REQUEST !== $event->get('request_type')) { - return; - } - $request = $event->get('request'); // disconnect all listeners from core.security to avoid the overhead // of most listeners having to do this manually $this->dispatcher->disconnect('core.security'); + array_push($this->listenersStack, $this->currentListeners); + // ensure that listeners disconnect from wherever they have connected to foreach ($this->currentListeners as $listener) { $listener->unregister($this->dispatcher); @@ -92,4 +91,29 @@ public function handle(EventInterface $event) return $ret; } } + + /** + * Reconnects super request firewall listeners after finishing a sub request. + * + * All firewall listeners of the sub request are disconnected from all their + * events. + * + * @param EventInterface $event An EventInterface instance + */ + public function handleResponse(EventInterface $event) + { + $this->dispatcher->disconnect('core.security'); + + foreach ($this->currentListeners as $listener) { + $listener->unregister($this->dispatcher); + } + + $listeners = array_pop($this->listenersStack); + + if (null !== $listeners) { + foreach ($listeners as $listener) { + $listener->reconnect($this->dispatcher); + } + } + } } diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php index 353185e218cca..dab33dffb64a0 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php @@ -121,6 +121,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles form based authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php index 555dadb2ceed5..e65ebf9d34922 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php @@ -64,6 +64,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles X509 authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php index 4aa1c552788d1..47b2e1aecd800 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php @@ -53,7 +53,7 @@ public function register(EventDispatcherInterface $dispatcher) { $dispatcher->connect('core.security', array($this, 'handle'), 0); } - + /** * {@inheritDoc} */ @@ -61,6 +61,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles access authorization. * diff --git a/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php index 05d23012e062c..b2fe133fbe6ad 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php @@ -55,6 +55,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles anonymous authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php index 972d081e77928..32acd15413fce 100644 --- a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php @@ -66,6 +66,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles basic authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php index 49cef7e35b95c..e4f2aa8872c03 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php @@ -54,6 +54,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles channel management. * diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index edc2f8cda5938..475995d7a0d15 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -69,6 +69,14 @@ public function unregister(EventDispatcherInterface $dispatcher) $dispatcher->disconnect('core.response', array($this, 'write')); } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + $dispatcher->connect('core.response', array($this, 'write'), 0); + } + /** * Reads the SecurityContext from the session. * diff --git a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php index 490e409058deb..7f7684422894a 100644 --- a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php @@ -69,6 +69,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles digest authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index 350b02905dac9..0ce069d369b67 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -70,6 +70,14 @@ public function unregister(EventDispatcherInterface $dispatcher) $dispatcher->disconnect('core.exception', array($this, 'handleException')); } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + $dispatcher->connect('core.exception', array($this, 'handleException'), 0); + } + /** * Handles security related exceptions. * diff --git a/src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php b/src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php index afb2d9f028c04..817a8522a0c32 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php +++ b/src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php @@ -15,7 +15,7 @@ /** * Interface that must be implemented by firewall listeners - * + * * @author Johannes M. Schmitt */ interface ListenerInterface @@ -39,4 +39,15 @@ function register(EventDispatcherInterface $dispatcher); * @param EventDispatcherInterface $dispatcher */ function unregister(EventDispatcherInterface $dispatcher); + + /** + * The implementation must reconnect this listener to all events it needs to + * handle after the core.security event. + * + * This method is called only if a sub request required the listeners to be + * unregistered. + * + * @param EventDispatcherInterface $dispatcher + */ + function reconnect(EventDispatcherInterface $dispatcher); } \ No newline at end of file diff --git a/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php b/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php index 1f5bc4524ce84..46a1b360f0d51 100644 --- a/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php @@ -78,6 +78,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Performs the logout if requested * diff --git a/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php b/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php index db9b6232c33ee..41dbfc519e150 100644 --- a/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php @@ -76,6 +76,14 @@ public function unregister(EventDispatcherInterface $dispatcher) $dispatcher->disconnect('core.response', array($this, 'updateCookies')); } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + $dispatcher->connect('core.response', array($this, 'updateCookies'), 0); + } + /** * Handles remember-me cookie based authentication. * diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index 4df51f0ed0ee0..d8d4bc8a1b73e 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -85,6 +85,13 @@ public function unregister(EventDispatcherInterface $dispatcher) { } + /** + * {@inheritDoc} + */ + public function reconnect(EventDispatcherInterface $dispatcher) + { + } + /** * Handles digest authentication. * pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy