From 44dbea63308ae8ac29b26d4e5ce9416c08870751 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 1 Aug 2018 16:08:30 +0200 Subject: [PATCH] [Security] Call AccessListener after LogoutListener --- .../Tests/Functional/LogoutTest.php | 10 +++++++ .../Functional/app/LogoutAccess/bundles.php | 18 +++++++++++++ .../Functional/app/LogoutAccess/config.yml | 26 +++++++++++++++++++ .../Functional/app/LogoutAccess/routing.yml | 5 ++++ .../Bundle/SecurityBundle/composer.json | 2 +- .../Component/Security/Http/Firewall.php | 13 ++++++++++ .../Security/Http/Tests/FirewallTest.php | 2 +- 7 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/config.yml create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/routing.yml diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php index d3c3b77fd5..15131290b4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php @@ -49,4 +49,14 @@ class LogoutTest extends WebTestCase $this->assertFalse($client->getContainer()->get('security.csrf.token_storage')->hasToken('foo')); } + + public function testAccessControlDoesNotApplyOnLogout() + { + $client = $this->createClient(array('test_case' => 'LogoutAccess', 'root_config' => 'config.yml')); + + $client->request('POST', '/login', array('_username' => 'johannes', '_password' => 'test')); + $client->request('GET', '/logout'); + + $this->assertRedirect($client->getResponse(), '/'); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php new file mode 100644 index 0000000000..c934b52aee --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Symfony\Bundle\SecurityBundle\SecurityBundle; + +return array( + new FrameworkBundle(), + new SecurityBundle(), +); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/config.yml new file mode 100644 index 0000000000..2e20735b80 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/config.yml @@ -0,0 +1,26 @@ +imports: +- { resource: ./../config/framework.yml } + +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + providers: + in_memory: + memory: + users: + johannes: { password: test, roles: [ROLE_USER] } + + firewalls: + default: + form_login: + check_path: login + remember_me: true + require_previous_session: false + logout: ~ + anonymous: ~ + stateless: true + + access_control: + - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: .*, roles: IS_AUTHENTICATED_FULLY } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/routing.yml new file mode 100644 index 0000000000..1dddfca2f8 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/routing.yml @@ -0,0 +1,5 @@ +login: + path: /login + +logout: + path: /logout diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index c0508ea29b..5e8d9458e6 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "ext-xml": "*", - "symfony/security": "^2.8.42|^3.4.12", + "symfony/security": "^2.8.45|^3.4.15", "symfony/security-acl": "~2.7|~3.0.0", "symfony/http-kernel": "~2.7|~3.0.0", "symfony/polyfill-php70": "~1.0" diff --git a/src/Symfony/Component/Security/Http/Firewall.php b/src/Symfony/Component/Security/Http/Firewall.php index b0a58e9a23..f089c04abe 100644 --- a/src/Symfony/Component/Security/Http/Firewall.php +++ b/src/Symfony/Component/Security/Http/Firewall.php @@ -16,6 +16,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Security\Http\Firewall\AccessListener; /** * Firewall uses a FirewallMap to register security listeners for the given @@ -58,8 +59,16 @@ class Firewall implements EventSubscriberInterface $exceptionListener->register($this->dispatcher); } + $accessListener = null; + // initiate the listener chain foreach ($authenticationListeners as $listener) { + if ($listener instanceof AccessListener) { + $accessListener = $listener; + + continue; + } + $listener->handle($event); if ($event->hasResponse()) { @@ -70,6 +79,10 @@ class Firewall implements EventSubscriberInterface if (null !== $logoutListener) { $logoutListener->handle($event); } + + if (!$event->hasResponse() && null !== $accessListener) { + $accessListener->handle($event); + } } public function onKernelFinishRequest(FinishRequestEvent $event) diff --git a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php index bd475bb4e5..66dad46152 100644 --- a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php +++ b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php @@ -79,7 +79,7 @@ class FirewallTest extends TestCase ->getMock() ; $event - ->expects($this->once()) + ->expects($this->at(0)) ->method('hasResponse') ->will($this->returnValue(true)) ;