FirewallMap.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\SecurityBundle\Security;
  11. use Psr\Container\ContainerInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\Security\Http\FirewallMapInterface;
  14. /**
  15. * This is a lazy-loading firewall map implementation.
  16. *
  17. * Listeners will only be initialized if we really need them.
  18. *
  19. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  20. */
  21. class FirewallMap implements FirewallMapInterface
  22. {
  23. private $container;
  24. private $map;
  25. public function __construct(ContainerInterface $container, iterable $map)
  26. {
  27. $this->container = $container;
  28. $this->map = $map;
  29. }
  30. public function getListeners(Request $request)
  31. {
  32. $context = $this->getFirewallContext($request);
  33. if (null === $context) {
  34. return [[], null, null];
  35. }
  36. return [$context->getListeners(), $context->getExceptionListener(), $context->getLogoutListener()];
  37. }
  38. /**
  39. * @return FirewallConfig|null
  40. */
  41. public function getFirewallConfig(Request $request)
  42. {
  43. $context = $this->getFirewallContext($request);
  44. if (null === $context) {
  45. return null;
  46. }
  47. return $context->getConfig();
  48. }
  49. private function getFirewallContext(Request $request): ?FirewallContext
  50. {
  51. if ($request->attributes->has('_firewall_context')) {
  52. $storedContextId = $request->attributes->get('_firewall_context');
  53. foreach ($this->map as $contextId => $requestMatcher) {
  54. if ($contextId === $storedContextId) {
  55. return $this->container->get($contextId);
  56. }
  57. }
  58. $request->attributes->remove('_firewall_context');
  59. }
  60. foreach ($this->map as $contextId => $requestMatcher) {
  61. if (null === $requestMatcher || $requestMatcher->matches($request)) {
  62. $request->attributes->set('_firewall_context', $contextId);
  63. return $this->container->get($contextId);
  64. }
  65. }
  66. return null;
  67. }
  68. }