From 66b9522fc1a462ab425020232372547b778c685e Mon Sep 17 00:00:00 2001 From: Gassan Gousseinov Date: Tue, 11 Jan 2022 20:16:52 +0100 Subject: [PATCH] Bugfix: InteractiveLoginEvent Event will be triggered also for OAuthAuthenticator. Fixes #1876 --- CHANGELOG.md | 1 + .../Http/Authenticator/OAuthAuthenticator.php | 8 ++++++- tests/Fixtures/CustomEventListener.php | 22 +++++++++++++++++++ tests/Functional/IntegrationTest.php | 17 +++++++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/Fixtures/CustomEventListener.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 431162574..a2c392b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Changelog * Enhancement: (@internal) Removed/replaced redundant argument `$firewallNames` from controllers. If controller class was copied and replaced, adapt list of arguments: In controller use `$resourceOwnerMapLocator->getFirewallNames()`. * Changed config files from `*.xml` to `*.php` (services and routes). Xml routing configs `connect.xml`, `login.xml` and `redirect.xml` are steel present but deprecated. Please use `*.php` variants in your includes instead. * Bugfix: RefreshTokenListener can not be lazy. If current firewall is lazy (or anonymous: lazy) then current auth token is often initializing on `kernel.response`. In this case new access token will not be stored in session. Therefore the expired token will be refreshed on each request. +* Bugfix: InteractiveLoginEvent will be triggered also for OAuthAuthenticator. ## 2.0.0-BETA1 (2021-12-10) * BC Break: Dropped PHP 7.3 support, diff --git a/src/Security/Http/Authenticator/OAuthAuthenticator.php b/src/Security/Http/Authenticator/OAuthAuthenticator.php index 10420deea..670d8dbae 100644 --- a/src/Security/Http/Authenticator/OAuthAuthenticator.php +++ b/src/Security/Http/Authenticator/OAuthAuthenticator.php @@ -30,6 +30,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; +use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; @@ -38,7 +39,7 @@ /** * @author Vadim Borodavko */ -final class OAuthAuthenticator implements AuthenticatorInterface, AuthenticationEntryPointInterface +final class OAuthAuthenticator implements AuthenticatorInterface, AuthenticationEntryPointInterface, InteractiveAuthenticatorInterface { private HttpUtils $httpUtils; private OAuthAwareUserProviderInterface $userProvider; @@ -262,6 +263,11 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio return $this->failureHandler->onAuthenticationFailure($request, $exception); } + public function isInteractive(): bool + { + return true; + } + private function extractCsrfTokenFromState(?string $stateParameter): ?string { $state = new State($stateParameter); diff --git a/tests/Fixtures/CustomEventListener.php b/tests/Fixtures/CustomEventListener.php new file mode 100644 index 000000000..05151b422 --- /dev/null +++ b/tests/Fixtures/CustomEventListener.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace HWI\Bundle\OAuthBundle\Tests\Fixtures; + +class CustomEventListener +{ + /** + * @param mixed $event + */ + public function handle($event): void + { + } +} diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index 65003a25d..c8d42e9f4 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -14,10 +14,12 @@ namespace HWI\Bundle\OAuthBundle\Tests\Functional; use HWI\Bundle\OAuthBundle\Tests\App\AppKernel; +use HWI\Bundle\OAuthBundle\Tests\Fixtures\CustomEventListener; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Http\SecurityEvents; final class IntegrationTest extends WebTestCase { @@ -85,7 +87,20 @@ function ($method, $url, $options) { $client = static::createClient(); $client->disableReboot(); - $client->getContainer()->set('hwi_oauth.http_client', $httpClient); + $container = $client->getContainer(); + $container->set('hwi_oauth.http_client', $httpClient); + + $interactiveLoginListener = $this->createMock(CustomEventListener::class); + $interactiveLoginListener->expects($this->once())->method('handle'); + // We attach our custom listener to prove InteractiveLoginEvent fired correctly. + // 'security.event_dispatcher.main' Dispatcher is used for Symfony 5.4 and 6.0 under php ^8.0 and ^8.1 + // and 'event_dispatcher' for all 4.4 and 5.4 under ^7.4 + foreach (['security.event_dispatcher.main', 'event_dispatcher'] as $dispatcherId) { + if ($container->has($dispatcherId)) { + $container->get($dispatcherId) + ->addListener(SecurityEvents::INTERACTIVE_LOGIN, [$interactiveLoginListener, 'handle']); + } + } $client->request('GET', $redirectLoginFromService);