-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #33676 [Security] add "anonymous: lazy" mode to firewalls (ni…
…colas-grekas) This PR was merged into the 4.4 branch. Discussion ---------- [Security] add "anonymous: lazy" mode to firewalls | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fixes #26769 et al. | License | MIT | Doc PR | - Contains #33663 until it is merged. This PR allows defining a firewall as such: ```yaml security: firewalls: main: anonymous: lazy ``` This means that the corresponding area should not start the session / load the user unless the application actively gets access to it. On pages that don't fetch the user at all, this means the session is not started, which means the corresponding token neither is. Lazily, when the user is accessed, e.g. via a call to `is_granted()`, the user is loaded, starting the session if needed. See #27817 for previous explanations on the topic also. Note that thanks to the logic in #33633, this PR doesn't have the drawback spotted in #27817: here, the profiler works as expected. Recipe update pending at symfony/recipes#649 Commits ------- 5cd1d7b [Security] add "anonymous: lazy" mode to firewalls
- Loading branch information
Showing
14 changed files
with
239 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
src/Symfony/Bundle/SecurityBundle/Security/LazyFirewallContext.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\SecurityBundle\Security; | ||
|
||
use Symfony\Component\HttpKernel\Event\RequestEvent; | ||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; | ||
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; | ||
use Symfony\Component\Security\Core\Exception\LazyResponseException; | ||
use Symfony\Component\Security\Http\AccessMapInterface; | ||
use Symfony\Component\Security\Http\Event\LazyResponseEvent; | ||
use Symfony\Component\Security\Http\Firewall\AccessListener; | ||
use Symfony\Component\Security\Http\Firewall\ExceptionListener; | ||
use Symfony\Component\Security\Http\Firewall\LogoutListener; | ||
|
||
/** | ||
* Lazily calls authentication listeners when actually required by the access listener. | ||
* | ||
* @author Nicolas Grekas <p@tchwork.com> | ||
*/ | ||
class LazyFirewallContext extends FirewallContext | ||
{ | ||
private $accessListener; | ||
private $tokenStorage; | ||
private $map; | ||
|
||
public function __construct(iterable $listeners, ?ExceptionListener $exceptionListener, ?LogoutListener $logoutListener, ?FirewallConfig $config, AccessListener $accessListener, TokenStorage $tokenStorage, AccessMapInterface $map) | ||
{ | ||
parent::__construct($listeners, $exceptionListener, $logoutListener, $config); | ||
|
||
$this->accessListener = $accessListener; | ||
$this->tokenStorage = $tokenStorage; | ||
$this->map = $map; | ||
} | ||
|
||
public function getListeners(): iterable | ||
{ | ||
return [$this]; | ||
} | ||
|
||
public function __invoke(RequestEvent $event) | ||
{ | ||
$this->tokenStorage->setInitializer(function () use ($event) { | ||
$event = new LazyResponseEvent($event); | ||
foreach (parent::getListeners() as $listener) { | ||
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($listener)), E_USER_DEPRECATED); | ||
$listener->handle($event); | ||
} | ||
} | ||
}); | ||
|
||
try { | ||
[$attributes] = $this->map->getPatterns($event->getRequest()); | ||
|
||
if ($attributes && [AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY] !== $attributes) { | ||
($this->accessListener)($event); | ||
} | ||
} catch (LazyResponseException $e) { | ||
$event->setResponse($e->getResponse()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
src/Symfony/Component/Security/Core/Exception/LazyResponseException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Security\Core\Exception; | ||
|
||
use Symfony\Component\HttpFoundation\Response; | ||
|
||
/** | ||
* A signaling exception that wraps a lazily computed response. | ||
* | ||
* @author Nicolas Grekas <p@tchwork.com> | ||
*/ | ||
class LazyResponseException extends \Exception implements ExceptionInterface | ||
{ | ||
private $response; | ||
|
||
public function __construct(Response $response) | ||
{ | ||
$this->response = $response; | ||
} | ||
|
||
public function getResponse(): Response | ||
{ | ||
return $this->response; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
src/Symfony/Component/Security/Http/Event/LazyResponseEvent.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Security\Http\Event; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Event\RequestEvent; | ||
use Symfony\Component\HttpKernel\HttpKernelInterface; | ||
use Symfony\Component\Security\Core\Exception\LazyResponseException; | ||
|
||
/** | ||
* Wraps a lazily computed response in a signaling exception. | ||
* | ||
* @author Nicolas Grekas <p@tchwork.com> | ||
*/ | ||
final class LazyResponseEvent extends RequestEvent | ||
{ | ||
private $event; | ||
|
||
public function __construct(parent $event) | ||
{ | ||
$this->event = $event; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function setResponse(Response $response) | ||
{ | ||
$this->stopPropagation(); | ||
$this->event->stopPropagation(); | ||
|
||
throw new LazyResponseException($response); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getKernel(): HttpKernelInterface | ||
{ | ||
return $this->event->getKernel(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getRequest(): Request | ||
{ | ||
return $this->event->getRequest(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getRequestType(): int | ||
{ | ||
return $this->event->getRequestType(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isMasterRequest(): bool | ||
{ | ||
return $this->event->isMasterRequest(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters