diff --git a/Security/Authorization/TwoFactorAccessDecider.php b/Security/Authorization/TwoFactorAccessDecider.php index afafdc0e..90a335c4 100644 --- a/Security/Authorization/TwoFactorAccessDecider.php +++ b/Security/Authorization/TwoFactorAccessDecider.php @@ -7,6 +7,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; +use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; use Symfony\Component\Security\Http\AccessMapInterface; use Symfony\Component\Security\Http\Firewall\AccessListener; use Symfony\Component\Security\Http\HttpUtils; @@ -50,10 +51,17 @@ public function isAccessible(Request $request, TokenInterface $token): bool { // Let routes pass, e.g. if a route needs to be callable during two-factor authentication list($attributes) = $this->accessMap->getPatterns($request); + + // Compatibility for Symfony 5.1 if (\defined(AccessListener::class.'::PUBLIC_ACCESS') && [AccessListener::PUBLIC_ACCESS] === $attributes) { return true; } + // Compatibility for Symfony 5.2+ + if (\defined(AuthenticatedVoter::class.'::PUBLIC_ACCESS') && [AuthenticatedVoter::PUBLIC_ACCESS] === $attributes) { + return true; + } + if (null !== $attributes && $this->accessDecisionManager->decide($token, $attributes, $request)) { return true; } diff --git a/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php b/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php index 2fd5592e..94204cb9 100644 --- a/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php +++ b/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php @@ -11,6 +11,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; +use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; use Symfony\Component\Security\Http\AccessMapInterface; use Symfony\Component\Security\Http\Firewall\AccessListener; use Symfony\Component\Security\Http\HttpUtils; @@ -137,8 +138,25 @@ public function isAccessible_pathAccessGranted_returnTrue(): void public function isAccessible_isPublic_returnTrue(): void { $this->requireAtLeastSymfony5_1(); + $publicAccess = null; - $this->stubAccessMapReturnsAttributes([AccessListener::PUBLIC_ACCESS]); + // Compatibility with Symfony 5.1 + if (\defined(AccessListener::class.'::PUBLIC_ACCESS')) { + $publicAccess = AccessListener::PUBLIC_ACCESS; + } + + // Compatibility for Symfony 5.2+ + if (\defined(AuthenticatedVoter::class.'::PUBLIC_ACCESS')) { + $publicAccess = AuthenticatedVoter::PUBLIC_ACCESS; + } + + if (null === $publicAccess) { + $this->fail('Could not find PUBLIC_ACCESS constant.'); + + return; + } + + $this->stubAccessMapReturnsAttributes([$publicAccess]); $this->whenRequestBaseUrl(''); $this->whenGeneratedLogoutPath(self::LOGOUT_PATH); $this->whenPathAccess(false);