diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php index c6ffa4527969b..9fd641b182cc1 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php @@ -91,7 +91,9 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio $this->logger?->debug('Authentication failure, redirect triggered.', ['failure_path' => $options['failure_path']]); - $request->getSession()->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $exception); + if (!$request->attributes->getBoolean('_stateless')) { + $request->getSession()->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $exception); + } return $this->httpUtils->createRedirectResponse($request, $options['failure_path']); } diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php index cb7c23b9c812d..9fabc046cedf5 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php @@ -103,7 +103,7 @@ protected function determineTargetUrl(Request $request): string } $firewallName = $this->getFirewallName(); - if (null !== $firewallName && $targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) { + if (null !== $firewallName && !$request->attributes->getBoolean('_stateless') && $targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) { $this->removeTargetPath($request->getSession(), $firewallName); return $targetUrl; diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php index e1f35a123bd64..5daf27dfe2032 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php @@ -46,6 +46,7 @@ protected function setUp(): void $this->session = $this->createMock(SessionInterface::class); $this->request = $this->createMock(Request::class); + $this->request->attributes = new ParameterBag(['_stateless' => false]); $this->request->expects($this->any())->method('getSession')->willReturn($this->session); $this->exception = $this->getMockBuilder(AuthenticationException::class)->onlyMethods(['getMessage'])->getMock(); } @@ -89,6 +90,17 @@ public function testExceptionIsPersistedInSession() $handler->onAuthenticationFailure($this->request, $this->exception); } + public function testExceptionIsNotPersistedInSessionOnStatelessRequest() + { + $this->request->attributes = new ParameterBag(['_stateless' => true]); + + $this->session->expects($this->never()) + ->method('set')->with(SecurityRequestAttributes::AUTHENTICATION_ERROR, $this->exception); + + $handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, [], $this->logger); + $handler->onAuthenticationFailure($this->request, $this->exception); + } + public function testExceptionIsPassedInRequestOnForward() { $options = ['failure_forward' => true]; diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php index 2d63821b42ccd..a9750223f0891 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php @@ -56,6 +56,25 @@ public function testRequestRedirectionsWithTargetPathInSessions() $this->assertSame('http://localhost/admin/dashboard', $handler->onAuthenticationSuccess($requestWithSession, $token)->getTargetUrl()); } + public function testStatelessRequestRedirections() + { + $session = $this->createMock(SessionInterface::class); + $session->expects($this->never())->method('get')->with('_security.admin.target_path'); + $session->expects($this->never())->method('remove')->with('_security.admin.target_path'); + $statelessRequest = Request::create('/'); + $statelessRequest->setSession($session); + $statelessRequest->attributes->set('_stateless', true); + + $urlGenerator = $this->createMock(UrlGeneratorInterface::class); + $urlGenerator->expects($this->any())->method('generate')->willReturn('http://localhost/login'); + $httpUtils = new HttpUtils($urlGenerator); + $token = $this->createMock(TokenInterface::class); + $handler = new DefaultAuthenticationSuccessHandler($httpUtils); + $handler->setFirewallName('admin'); + + $this->assertSame('http://localhost/', $handler->onAuthenticationSuccess($statelessRequest, $token)->getTargetUrl()); + } + public static function getRequestRedirections() { return [