diff --git a/UPGRADE-5.4.md b/UPGRADE-5.4.md index 9c81e39a2f9cd..11c39d2038008 100644 --- a/UPGRADE-5.4.md +++ b/UPGRADE-5.4.md @@ -11,3 +11,17 @@ HttpKernel ---------- * Deprecate `AbstractTestSessionListener::getSession` inject a session in the request instead + +SecurityBundle +-------------- + + * Deprecate the `always_authenticate_before_granting` option + +Security +-------- + + * Deprecate setting the 4th argument (`$alwaysAuthenticate`) to `true` and not setting the + 5th argument (`$exceptionOnNoToken`) to `false` of `AuthorizationChecker` (this is the default + behavior when using `enable_authenticator_manager: true`) + * Deprecate not setting the 5th argument (`$exceptionOnNoToken`) of `AccessListener` to `false` + (this is the default behavior when using `enable_authenticator_manager: true`) diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md index 30f6f1fa5861f..c74d8f487a49d 100644 --- a/UPGRADE-6.0.md +++ b/UPGRADE-6.0.md @@ -194,6 +194,8 @@ Routing Security -------- + * Remove the 4th and 5th argument of `AuthorizationChecker` + * Remove the 5th argument of `AccessListener` * Remove class `User`, use `InMemoryUser` or your own implementation instead. If you are using the `isAccountNonLocked()`, `isAccountNonExpired()` or `isCredentialsNonExpired()` method, consider re-implementing them in your own user class as they are not part of the `InMemoryUser` API @@ -313,6 +315,7 @@ Security SecurityBundle -------------- + * Remove the `always_authenticate_before_granting` option * Remove the `UserPasswordEncoderCommand` class and the corresponding `user:encode-password` command, use `UserPasswordHashCommand` and `user:hash-password` instead * Remove the `security.encoder_factory.generic` service, the `security.encoder_factory` and `Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface` aliases, diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md index 640f0d2ce3393..807e75536a005 100644 --- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.4 +--- + + * Deprecate the `always_authenticate_before_granting` option + 5.3 --- diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 942e27d7ec109..280a62030472c 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -90,7 +90,10 @@ public function getConfigTreeBuilder() ->defaultValue(SessionAuthenticationStrategy::MIGRATE) ->end() ->booleanNode('hide_user_not_found')->defaultTrue()->end() - ->booleanNode('always_authenticate_before_granting')->defaultFalse()->end() + ->booleanNode('always_authenticate_before_granting') + ->defaultFalse() + ->setDeprecated('symfony/security-bundle', '5.4') + ->end() ->booleanNode('erase_credentials')->defaultTrue()->end() ->booleanNode('enable_authenticator_manager')->defaultFalse()->info('Enables the new Symfony Security system based on Authenticators, all used authenticators must support this before enabling this.')->end() ->arrayNode('access_decision_manager') diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 3df35509237c9..7f10b77abb184 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -635,6 +635,9 @@ public function provideEntryPointRequiredData() ]; } + /** + * @group legacy + */ public function testAlwaysAuthenticateBeforeGrantingCannotBeTrueWithAuthenticatorManager() { $this->expectException(InvalidConfigurationException::class); diff --git a/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php b/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php index c51551a0d5807..ef678b547a259 100644 --- a/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php +++ b/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php @@ -34,6 +34,13 @@ class AuthorizationChecker implements AuthorizationCheckerInterface public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, bool $alwaysAuthenticate = false, bool $exceptionOnNoToken = true) { + if (false !== $alwaysAuthenticate) { + trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 4th argument of "%s" to "false" is deprecated.', __METHOD__); + } + if (false !== $exceptionOnNoToken) { + trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 5th argument of "%s" to "false" is deprecated.', __METHOD__); + } + $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->accessDecisionManager = $accessDecisionManager; diff --git a/src/Symfony/Component/Security/Core/CHANGELOG.md b/src/Symfony/Component/Security/Core/CHANGELOG.md index 22652b086195b..459ae577342e8 100644 --- a/src/Symfony/Component/Security/Core/CHANGELOG.md +++ b/src/Symfony/Component/Security/Core/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +5.4 +--- + + * Deprecate setting the 4th argument (`$alwaysAuthenticate`) to `true` and not setting the + 5th argument (`$exceptionOnNoToken`) to `false` of `AuthorizationChecker` + 5.3 --- diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php index 8bbb27dff2fe4..38554de0a1c9a 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php @@ -36,7 +36,9 @@ protected function setUp(): void $this->authorizationChecker = new AuthorizationChecker( $this->tokenStorage, $this->authenticationManager, - $this->accessDecisionManager + $this->accessDecisionManager, + false, + false ); } @@ -71,13 +73,23 @@ public function testVoteAuthenticatesTokenIfNecessary() $this->assertSame($newToken, $this->tokenStorage->getToken()); } - public function testVoteWithoutAuthenticationToken() + /** + * @group legacy + */ + public function testLegacyVoteWithoutAuthenticationToken() { + $authorizationChecker = new AuthorizationChecker( + $this->tokenStorage, + $this->authenticationManager, + $this->accessDecisionManager + ); + $this->expectException(AuthenticationCredentialsNotFoundException::class); - $this->authorizationChecker->isGranted('ROLE_FOO'); + + $authorizationChecker->isGranted('ROLE_FOO'); } - public function testVoteWithoutAuthenticationTokenAndExceptionOnNoTokenIsFalse() + public function testVoteWithoutAuthenticationToken() { $authorizationChecker = new AuthorizationChecker($this->tokenStorage, $this->authenticationManager, $this->accessDecisionManager, false, false); diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php index 09559788ed06e..32d196f6d76ba 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php @@ -37,7 +37,7 @@ public function testIsAuthenticated($token, $expression, $result) $tokenStorage = new TokenStorage(); $tokenStorage->setToken($token); $accessDecisionManager = new AccessDecisionManager([new RoleVoter(), new AuthenticatedVoter($trustResolver)]); - $authChecker = new AuthorizationChecker($tokenStorage, $this->createMock(AuthenticationManagerInterface::class), $accessDecisionManager); + $authChecker = new AuthorizationChecker($tokenStorage, $this->createMock(AuthenticationManagerInterface::class), $accessDecisionManager, false, false); $context = []; $context['auth_checker'] = $authChecker; diff --git a/src/Symfony/Component/Security/Http/CHANGELOG.md b/src/Symfony/Component/Security/Http/CHANGELOG.md index 22652b086195b..1bb5da6d0218a 100644 --- a/src/Symfony/Component/Security/Http/CHANGELOG.md +++ b/src/Symfony/Component/Security/Http/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.4 +--- + + * Deprecate not setting the 5th argument (`$exceptionOnNoToken`) of `AccessListener` to `false` + 5.3 --- diff --git a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php index ec6b0b79e1e37..fdb219a1d61ea 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php @@ -40,6 +40,10 @@ class AccessListener extends AbstractListener public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager, bool $exceptionOnNoToken = true) { + if (false !== $exceptionOnNoToken) { + trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 5th argument of "%s" to "false" is deprecated.', __METHOD__); + } + $this->tokenStorage = $tokenStorage; $this->accessDecisionManager = $accessDecisionManager; $this->map = $map; diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php index aac67379b4e7f..cbed2baebdc69 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php @@ -71,7 +71,9 @@ public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess() $tokenStorage, $accessDecisionManager, $accessMap, - $this->createMock(AuthenticationManagerInterface::class) + $this->createMock(AuthenticationManagerInterface::class), + false, + false ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -135,7 +137,9 @@ public function testHandleWhenTheTokenIsNotAuthenticated() $tokenStorage, $accessDecisionManager, $accessMap, - $authManager + $authManager, + false, + false ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -170,7 +174,9 @@ public function testHandleWhenThereIsNoAccessMapEntryMatchingTheRequest() $tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), $accessMap, - $this->createMock(AuthenticationManagerInterface::class) + $this->createMock(AuthenticationManagerInterface::class), + false, + false ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -198,7 +204,9 @@ public function testHandleWhenAccessMapReturnsEmptyAttributes() $tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), $accessMap, - $this->createMock(AuthenticationManagerInterface::class) + $this->createMock(AuthenticationManagerInterface::class), + false, + false ); $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); @@ -206,7 +214,10 @@ public function testHandleWhenAccessMapReturnsEmptyAttributes() $listener(new LazyResponseEvent($event)); } - public function testHandleWhenTheSecurityTokenStorageHasNoToken() + /** + * @group legacy + */ + public function testLegacyHandleWhenTheSecurityTokenStorageHasNoToken() { $this->expectException(AuthenticationCredentialsNotFoundException::class); $tokenStorage = $this->createMock(TokenStorageInterface::class); @@ -236,7 +247,7 @@ public function testHandleWhenTheSecurityTokenStorageHasNoToken() $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); } - public function testHandleWhenTheSecurityTokenStorageHasNoTokenAndExceptionOnTokenIsFalse() + public function testHandleWhenTheSecurityTokenStorageHasNoToken() { $this->expectException(AccessDeniedException::class); $tokenStorage = new TokenStorage(); @@ -260,13 +271,14 @@ public function testHandleWhenTheSecurityTokenStorageHasNoTokenAndExceptionOnTok $accessDecisionManager, $accessMap, $this->createMock(AuthenticationManagerInterface::class), + false, false ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); } - public function testHandleWhenPublicAccessIsAllowedAndExceptionOnTokenIsFalse() + public function testHandleWhenPublicAccessIsAllowed() { $tokenStorage = new TokenStorage(); $request = new Request(); @@ -289,6 +301,7 @@ public function testHandleWhenPublicAccessIsAllowedAndExceptionOnTokenIsFalse() $accessDecisionManager, $accessMap, $this->createMock(AuthenticationManagerInterface::class), + false, false ); @@ -320,6 +333,7 @@ public function testHandleWhenPublicAccessWhileAuthenticated() $accessDecisionManager, $accessMap, $this->createMock(AuthenticationManagerInterface::class), + false, false ); @@ -355,7 +369,9 @@ public function testHandleMWithultipleAttributesShouldBeHandledAsAnd() $tokenStorage, $accessDecisionManager, $accessMap, - $this->createMock(AuthenticationManagerInterface::class) + $this->createMock(AuthenticationManagerInterface::class), + false, + false ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST));