diff --git a/Firewall/AccessListener.php b/Firewall/AccessListener.php index 00673f60..b2944568 100644 --- a/Firewall/AccessListener.php +++ b/Firewall/AccessListener.php @@ -87,15 +87,7 @@ public function authenticate(RequestEvent $event) $this->tokenStorage->setToken($token); } - $granted = false; - foreach ($attributes as $key => $value) { - if ($this->accessDecisionManager->decide($token, [$key => $value], $request)) { - $granted = true; - break; - } - } - - if (!$granted) { + if (!$this->accessDecisionManager->decide($token, $attributes, $request, true)) { $exception = new AccessDeniedException(); $exception->setAttributes($attributes); $exception->setSubject($request); diff --git a/Tests/Firewall/AccessListenerTest.php b/Tests/Firewall/AccessListenerTest.php index 168e2564..75798d05 100644 --- a/Tests/Firewall/AccessListenerTest.php +++ b/Tests/Firewall/AccessListenerTest.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\Security\Http\AccessMapInterface; @@ -227,4 +228,44 @@ public function testHandleWhenTheSecurityTokenStorageHasNoToken() $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST)); } + + public function testHandleMWithultipleAttributesShouldBeHandledAsAnd() + { + $request = new Request(); + + $accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock(); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->willReturn([['foo' => 'bar', 'bar' => 'baz'], null]) + ; + + $authenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); + $authenticatedToken + ->expects($this->any()) + ->method('isAuthenticated') + ->willReturn(true) + ; + + $tokenStorage = new TokenStorage(); + $tokenStorage->setToken($authenticatedToken); + + $accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock(); + $accessDecisionManager + ->expects($this->once()) + ->method('decide') + ->with($this->equalTo($authenticatedToken), $this->equalTo(['foo' => 'bar', 'bar' => 'baz']), $this->equalTo($request), true) + ->willReturn(true) + ; + + $listener = new AccessListener( + $tokenStorage, + $accessDecisionManager, + $accessMap, + $this->createMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface') + ); + + $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST)); + } } diff --git a/composer.json b/composer.json index 7c9cdb48..699ffcf7 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1.3", - "symfony/security-core": "^4.4", + "symfony/security-core": "^4.4.7", "symfony/http-foundation": "^3.4.40|^4.4.7|^5.0.7", "symfony/http-kernel": "^4.4", "symfony/property-access": "^3.4|^4.0|^5.0"