Skip to content

[Security][SecurityBundle] Firewall subrequest reconnections #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
</service>

<service id="security.encoder_factory" alias="security.encoder_factory.generic"></service>

<service id="security.account_checker" class="%security.account_checker.class%" public="false" />


Expand Down Expand Up @@ -107,6 +107,7 @@
<!-- Firewall related services -->
<service id="security.firewall" class="%security.firewall.class%">
<tag name="kernel.listener" event="core.request" method="handle" priority="-128" />
<tag name="kernel.listener" event="core.response" method="handleResponse" priority="128" />
<argument type="service" id="security.firewall.map" />
<argument type="service" id="event_dispatcher" />
</service>
Expand Down
32 changes: 28 additions & 4 deletions src/Symfony/Component/Security/Http/Firewall.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Firewall
protected $map;
protected $dispatcher;
protected $currentListeners;
protected $listenersStack;

/**
* Constructor.
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles form based authentication.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles X509 authentication.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,21 @@ public function register(EventDispatcherInterface $dispatcher)
{
$dispatcher->connect('core.security', array($this, 'handle'), 0);
}

/**
* {@inheritDoc}
*/
public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles access authorization.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles anonymous authentication.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles basic authentication.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles channel management.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles digest authentication.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

/**
* Interface that must be implemented by firewall listeners
*
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface ListenerInterface
Expand All @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Performs the logout if requested
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ public function unregister(EventDispatcherInterface $dispatcher)
{
}

/**
* {@inheritDoc}
*/
public function reconnect(EventDispatcherInterface $dispatcher)
{
}

/**
* Handles digest authentication.
*
Expand Down