diff --git a/UPGRADE-5.4.md b/UPGRADE-5.4.md index 2a715accd0ed5..2cccd102addfe 100644 --- a/UPGRADE-5.4.md +++ b/UPGRADE-5.4.md @@ -62,6 +62,30 @@ Security * Deprecate `AnonymousToken`, as the related authenticator was deprecated in 5.3 * Deprecate `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions) * Deprecate not returning an `UserInterface` from `Token::getUser()` + * Deprecate `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`, + use `AuthenticatedVoter::PUBLIC_ACCESS` instead. + + Before: + ```yaml + # config/packages/security.yaml + security: + # ... + access_control: + - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } + ``` + + After: + ```yaml + # config/packages/security.yaml + security: + # ... + access_control: + - { path: ^/login, roles: PUBLIC_ACCESS } + ``` + + * Deprecate `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression function + as anonymous no longer exists in version 6, use the `isFullFledged()` or the new `isAuthenticated()` instead + if you want to check if the request is (fully) authenticated. * Deprecate the `$authManager` argument of `AccessListener`, the argument will be removed * Deprecate the `$authenticationManager` argument of the `AuthorizationChecker` constructor, the argument will be removed * Deprecate setting the `$alwaysAuthenticate` argument to `true` and not setting the diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md index bbc662be3d51b..9fd237c2def19 100644 --- a/UPGRADE-6.0.md +++ b/UPGRADE-6.0.md @@ -210,6 +210,30 @@ Security * Remove `AnonymousToken` * Remove `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions) * Restrict the return type of `Token::getUser()` to `UserInterface` (removing `string|\Stringable`) + * Remove `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`, + use `AuthenticatedVoter::PUBLIC_ACCESS` instead. + + Before: + ```yaml + # config/packages/security.yaml + security: + # ... + access_control: + - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } + ``` + + After: + ```yaml + # config/packages/security.yaml + security: + # ... + access_control: + - { path: ^/login, roles: PUBLIC_ACCESS } + ``` + + * Remove `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression function + as anonymous no longer exists in version 6, use the `isFullFledged()` or the new `isAuthenticated()` instead + if you want to check if the request is (fully) authenticated. * Remove the 4th and 5th argument of `AuthorizationChecker` * Remove the 5th argument of `AccessListener` * Remove class `User`, use `InMemoryUser` or your own implementation instead. diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md index 09f87c7a6b837..7f661ddb085ed 100644 --- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 5.4 --- + * Deprecate `FirewallConfig::allowsAnonymous()` and the `allows_anonymous` from the data collector data, there will be no anonymous concept as of version 6. * Deprecate not setting `$authenticatorManagerEnabled` to `true` in `SecurityDataCollector` and `DebugFirewallCommand` * Deprecate `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of `AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()` diff --git a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php index a4df1649cbbb8..a0f38899d8edf 100644 --- a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php +++ b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php @@ -184,7 +184,7 @@ public function collect(Request $request, Response $response, \Throwable $except if (null !== $firewallConfig) { $this->data['firewall'] = [ 'name' => $firewallConfig->getName(), - 'allows_anonymous' => $firewallConfig->allowsAnonymous(), + 'allows_anonymous' => $this->authenticatorManagerEnabled ? false : $firewallConfig->allowsAnonymous(), 'request_matcher' => $firewallConfig->getRequestMatcher(), 'security_enabled' => $firewallConfig->isSecurityEnabled(), 'stateless' => $firewallConfig->isStateless(), diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php index 1a78dd2f4aa72..779920b5a4320 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php @@ -64,8 +64,13 @@ public function isSecurityEnabled(): bool return $this->securityEnabled; } + /** + * @deprecated since Symfony 5.4 + */ public function allowsAnonymous(): bool { + trigger_deprecation('symfony/security-bundle', '5.4', 'The "%s()" method is deprecated.', __METHOD__); + return \in_array('anonymous', $this->listeners, true); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php index 231417c12b013..a25a43b53c53d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php @@ -141,7 +141,6 @@ public function testGetFirewall() $collected = $collector->getFirewall(); $this->assertSame($firewallConfig->getName(), $collected['name']); - $this->assertSame($firewallConfig->allowsAnonymous(), $collected['allows_anonymous']); $this->assertSame($firewallConfig->getRequestMatcher(), $collected['request_matcher']); $this->assertSame($firewallConfig->isSecurityEnabled(), $collected['security_enabled']); $this->assertSame($firewallConfig->isStateless(), $collected['stateless']); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml index b0543f9808d88..fce16794f7092 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml @@ -53,5 +53,5 @@ security: - { path: ^/secured-by-one-env-placeholder-and-one-real-ip$, ips: ['%env(APP_IP)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/secured-by-one-env-placeholder-multiple-ips-and-one-real-ip$, ips: ['%env(APP_IPS)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/highly_protected_resource$, roles: IS_ADMIN } - - { path: ^/protected-via-expression$, allow_if: "(is_anonymous() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" } + - { path: ^/protected-via-expression$, allow_if: "(!is_authenticated() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" } - { path: .*, roles: IS_AUTHENTICATED_FULLY } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php index 99e897aa8ff20..be741ecc30c41 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php @@ -18,7 +18,7 @@ class FirewallConfigTest extends TestCase { public function testGetters() { - $listeners = ['logout', 'remember_me', 'anonymous']; + $listeners = ['logout', 'remember_me']; $options = [ 'request_matcher' => 'foo_request_matcher', 'security' => false, @@ -57,7 +57,6 @@ public function testGetters() $this->assertSame($options['access_denied_handler'], $config->getAccessDeniedHandler()); $this->assertSame($options['access_denied_url'], $config->getAccessDeniedUrl()); $this->assertSame($options['user_checker'], $config->getUserChecker()); - $this->assertTrue($config->allowsAnonymous()); $this->assertSame($listeners, $config->getListeners()); $this->assertSame($options['switch_user'], $config->getSwitchUser()); } diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php index 249d8d1cf15fc..c8fa3f54b9b2e 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php @@ -23,11 +23,22 @@ */ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterface { + public function isAuthenticated(TokenInterface $token = null): bool + { + return null !== $token && !$token instanceof NullToken + // @deprecated since Symfony 5.4, TokenInterface::isAuthenticated() and AnonymousToken no longer exists in 6.0 + && !$token instanceof AnonymousToken && $token->isAuthenticated(false); + } + /** * {@inheritdoc} */ - public function isAnonymous(TokenInterface $token = null) + public function isAnonymous(TokenInterface $token = null/*, $deprecation = true*/) { + if (1 === \func_num_args() || false !== func_get_arg(1)) { + trigger_deprecation('symfony/security-core', '5.4', 'The "%s()" method is deprecated, use "isAuthenticated()" or "isFullFledged()" if you want to check if the request is (fully) authenticated.', __METHOD__); + } + if (null === $token) { return false; } @@ -56,6 +67,6 @@ public function isFullFledged(TokenInterface $token = null) return false; } - return !$this->isAnonymous($token) && !$this->isRememberMe($token); + return !$this->isAnonymous($token, false) && !$this->isRememberMe($token); } } diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php index 6c9c4cbb37efa..1122ffef629af 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php @@ -17,6 +17,8 @@ * Interface for resolving the authentication status of a given token. * * @author Johannes M. Schmitt + * + * @method bool isAuthenticated(TokenInterface $token = null) */ interface AuthenticationTrustResolverInterface { @@ -27,6 +29,8 @@ interface AuthenticationTrustResolverInterface * If null is passed, the method must return false. * * @return bool + * + * @deprecated since Symfony 5.4, use !isAuthenticated() instead */ public function isAnonymous(TokenInterface $token = null); diff --git a/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php b/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php index d8ff9d01f9643..ba2ba26462b91 100644 --- a/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php +++ b/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php @@ -13,6 +13,7 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunction; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; /** * Define some ExpressionLanguage functions. @@ -25,15 +26,18 @@ public function getFunctions() { return [ new ExpressionFunction('is_anonymous', function () { - return '$token && $auth_checker->isGranted("IS_ANONYMOUS")'; + return 'trigger_deprecation("symfony/security-core", "5.4", "The \"is_anonymous()\" expression function is deprecated.") || ($token && $auth_checker->isGranted("IS_ANONYMOUS"))'; }, function (array $variables) { + trigger_deprecation('symfony/security-core', '5.4', 'The "is_anonymous()" expression function is deprecated.'); + return $variables['token'] && $variables['auth_checker']->isGranted('IS_ANONYMOUS'); }), + // @deprecated remove the ternary and always use IS_AUTHENTICATED in 6.0 new ExpressionFunction('is_authenticated', function () { - return '$token && !$auth_checker->isGranted("IS_ANONYMOUS")'; + return 'defined("'.AuthenticatedVoter::class.'::IS_AUTHENTICATED") ? $auth_checker->isGranted("IS_AUTHENTICATED") : ($token && !$auth_checker->isGranted("IS_ANONYMOUS"))'; }, function (array $variables) { - return $variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS'); + return \defined(AuthenticatedVoter::class.'::IS_AUTHENTICATED') ? $variables['auth_checker']->isGranted('IS_AUTHENTICATED') : ($variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS')); }), new ExpressionFunction('is_fully_authenticated', function () { diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php index fd6a65f2bc8d4..1acfbb879674d 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php @@ -12,12 +12,13 @@ namespace Symfony\Component\Security\Core\Authorization\Voter; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\NullToken; use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; /** * AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY, - * IS_AUTHENTICATED_REMEMBERED, or IS_AUTHENTICATED_ANONYMOUSLY is present. + * IS_AUTHENTICATED_REMEMBERED, IS_AUTHENTICATED is present. * * This list is most restrictive to least restrictive checking. * @@ -28,8 +29,15 @@ class AuthenticatedVoter implements VoterInterface { public const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY'; public const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED'; + /** + * @deprecated since Symfony 5.4 + */ public const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY'; + /** + * @deprecated since Symfony 5.4 + */ public const IS_ANONYMOUS = 'IS_ANONYMOUS'; + public const IS_AUTHENTICATED = 'IS_AUTHENTICATED'; public const IS_IMPERSONATOR = 'IS_IMPERSONATOR'; public const IS_REMEMBERED = 'IS_REMEMBERED'; public const PUBLIC_ACCESS = 'PUBLIC_ACCESS'; @@ -55,6 +63,7 @@ public function vote(TokenInterface $token, $subject, array $attributes) if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute && self::IS_AUTHENTICATED_REMEMBERED !== $attribute && self::IS_AUTHENTICATED_ANONYMOUSLY !== $attribute + && self::IS_AUTHENTICATED !== $attribute && self::IS_ANONYMOUS !== $attribute && self::IS_IMPERSONATOR !== $attribute && self::IS_REMEMBERED !== $attribute)) { @@ -78,6 +87,16 @@ public function vote(TokenInterface $token, $subject, array $attributes) && ($this->authenticationTrustResolver->isAnonymous($token) || $this->authenticationTrustResolver->isRememberMe($token) || $this->authenticationTrustResolver->isFullFledged($token))) { + trigger_deprecation('symfony/security-core', '5.4', 'The "IS_AUTHENTICATED_ANONYMOUSLY" security attribute is deprecated, use "IS_AUTHENTICATED" or "IS_AUTHENTICATED_FULLY" instead if you want to check if the request is (fully) authenticated.'); + + return VoterInterface::ACCESS_GRANTED; + } + + // @deprecated $this->authenticationTrustResolver must implement isAuthenticated() in 6.0 + if (self::IS_AUTHENTICATED === $attribute + && (method_exists($this->authenticationTrustResolver, 'isAuthenticated') + ? $this->authenticationTrustResolver->isAuthenticated($token) + : (null !== $token && !$token instanceof NullToken))) { return VoterInterface::ACCESS_GRANTED; } @@ -86,6 +105,8 @@ public function vote(TokenInterface $token, $subject, array $attributes) } if (self::IS_ANONYMOUS === $attribute && $this->authenticationTrustResolver->isAnonymous($token)) { + trigger_deprecation('symfony/security-core', '5.4', 'The "IS_ANONYMOUSLY" security attribute is deprecated, anonymous no longer exists in version 6.'); + return VoterInterface::ACCESS_GRANTED; } diff --git a/src/Symfony/Component/Security/Core/CHANGELOG.md b/src/Symfony/Component/Security/Core/CHANGELOG.md index 90a1353ff4bd9..1b27004f67477 100644 --- a/src/Symfony/Component/Security/Core/CHANGELOG.md +++ b/src/Symfony/Component/Security/Core/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG * Deprecate `AnonymousToken`, as the related authenticator was deprecated in 5.3 * Deprecate `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions) * Deprecate returning `string|\Stringable` from `Token::getUser()` (it must return a `UserInterface`) + * Deprecate `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`, + use `AuthenticatedVoter::IS_AUTHENTICATED_FULLY` or `AuthenticatedVoter::IS_AUTHENTICATED` instead. + * Deprecate `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression + function as anonymous no longer exists in version 6, use the `isFullFledged()` or the new + `isAuthenticated()` instead if you want to check if the request is (fully) authenticated. * Deprecate the `$authenticationManager` argument of the `AuthorizationChecker` constructor * Deprecate setting the `$alwaysAuthenticate` argument to `true` and not setting the `$exceptionOnNoToken` argument to `false` of `AuthorizationChecker` diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php index 8ce8647be02cd..9113d064aacdc 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php @@ -16,9 +16,14 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\User\InMemoryUser; +use Symfony\Component\Security\Core\User\User; class AuthenticationTrustResolverTest extends TestCase { + /** + * @group legacy + */ public function testIsAnonymous() { $resolver = new AuthenticationTrustResolver(); @@ -50,6 +55,17 @@ public function testisFullFledged() $this->assertTrue($resolver->isFullFledged(new FakeCustomToken())); } + public function testIsAuthenticated() + { + $resolver = new AuthenticationTrustResolver(); + $this->assertFalse($resolver->isAuthenticated(null)); + $this->assertTrue($resolver->isAuthenticated($this->getRememberMeToken())); + $this->assertTrue($resolver->isAuthenticated(new FakeCustomToken())); + } + + /** + * @group legacy + */ public function testIsAnonymousWithClassAsConstructorButStillExtending() { $resolver = $this->getResolver(); @@ -102,7 +118,7 @@ protected function getToken() protected function getAnonymousToken() { - return $this->getMockBuilder(AnonymousToken::class)->setConstructorArgs(['', ''])->getMock(); + return new AnonymousToken('secret', 'anon.'); } private function getRealCustomAnonymousToken() @@ -116,7 +132,9 @@ public function __construct() protected function getRememberMeToken() { - return $this->getMockBuilder(RememberMeToken::class)->setMethods(['setPersistent'])->disableOriginalConstructor()->getMock(); + $user = class_exists(InMemoryUser::class) ? new InMemoryUser('wouter', '', ['ROLE_USER']) : new User('wouter', '', ['ROLE_USER']); + + return new RememberMeToken($user, 'main', 'secret'); } protected function getResolver() @@ -176,6 +194,7 @@ public function getUserIdentifier(): string public function isAuthenticated(): bool { + return true; } public function setAuthenticated(bool $isAuthenticated) diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php index 759921685b56d..c76ca77dfbbf5 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php @@ -28,7 +28,6 @@ class ExpressionLanguageTest extends TestCase { /** * @dataProvider provider - * @dataProvider legacyProvider */ public function testIsAuthenticated($token, $expression, $result) { @@ -56,19 +55,16 @@ public function provider() $usernamePasswordToken = new UsernamePasswordToken($user, 'firewall-name', $roles); return [ - [$noToken, 'is_anonymous()', false], [$noToken, 'is_authenticated()', false], [$noToken, 'is_fully_authenticated()', false], [$noToken, 'is_remember_me()', false], - [$rememberMeToken, 'is_anonymous()', false], [$rememberMeToken, 'is_authenticated()', true], [$rememberMeToken, 'is_fully_authenticated()', false], [$rememberMeToken, 'is_remember_me()', true], [$rememberMeToken, "is_granted('ROLE_FOO')", false], [$rememberMeToken, "is_granted('ROLE_USER')", true], - [$usernamePasswordToken, 'is_anonymous()', false], [$usernamePasswordToken, 'is_authenticated()', true], [$usernamePasswordToken, 'is_fully_authenticated()', true], [$usernamePasswordToken, 'is_remember_me()', false], @@ -77,11 +73,22 @@ public function provider() ]; } + /** + * @dataProvider legacyProvider + * @group legacy + */ + public function testLegacyIsAuthenticated($token, $expression, $result) + { + $this->testIsAuthenticated($token, $expression, $result); + } + /** * @group legacy */ public function legacyProvider() { + $roles = ['ROLE_USER', 'ROLE_ADMIN']; + $user = new InMemoryUser('username', 'password', $roles); $anonymousToken = new AnonymousToken('firewall', 'anon.'); return [ @@ -90,6 +97,10 @@ public function legacyProvider() [$anonymousToken, 'is_fully_authenticated()', false], [$anonymousToken, 'is_remember_me()', false], [$anonymousToken, "is_granted('ROLE_USER')", false], + + [null, 'is_anonymous()', false], + [new RememberMeToken($user, 'firewall-name', 'firewall'), 'is_anonymous()', false], + [new UsernamePasswordToken($user, 'firewall-name', $roles), 'is_anonymous()', false], ]; } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php index 0fc5dce610f2e..c2de6c1fca440 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php @@ -40,18 +40,12 @@ public function getVoteTests() ['remembered', [], VoterInterface::ACCESS_ABSTAIN], ['remembered', ['FOO'], VoterInterface::ACCESS_ABSTAIN], - ['fully', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ['remembered', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ['fully', ['IS_AUTHENTICATED_REMEMBERED'], VoterInterface::ACCESS_GRANTED], ['remembered', ['IS_AUTHENTICATED_REMEMBERED'], VoterInterface::ACCESS_GRANTED], ['fully', ['IS_AUTHENTICATED_FULLY'], VoterInterface::ACCESS_GRANTED], ['remembered', ['IS_AUTHENTICATED_FULLY'], VoterInterface::ACCESS_DENIED], - ['fully', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], - ['remembered', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], - ['fully', ['IS_IMPERSONATOR'], VoterInterface::ACCESS_DENIED], ['remembered', ['IS_IMPERSONATOR'], VoterInterface::ACCESS_DENIED], ['impersonated', ['IS_IMPERSONATOR'], VoterInterface::ACCESS_GRANTED], @@ -77,6 +71,14 @@ public function getLegacyVoteTests() ['anonymously', ['IS_AUTHENTICATED_FULLY'], VoterInterface::ACCESS_DENIED], ['anonymously', ['IS_ANONYMOUS'], VoterInterface::ACCESS_GRANTED], ['anonymously', ['IS_IMPERSONATOR'], VoterInterface::ACCESS_DENIED], + + ['fully', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], + ['remembered', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], + ['anonymously', ['IS_ANONYMOUS'], VoterInterface::ACCESS_GRANTED], + + ['fully', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], + ['remembered', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], + ['anonymously', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], ]; } diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 567b4b2e37611..2b82aa1a4b22b 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -187,7 +187,9 @@ public function onKernelResponse(ResponseEvent $event) $usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : null; $token = $this->tokenStorage->getToken(); - if (null === $token || $this->trustResolver->isAnonymous($token)) { + // @deprecated always use isAuthenticated() in 6.0 + $notAuthenticated = method_exists($this->trustResolver, 'isAuthenticated') ? !$this->trustResolver->isAuthenticated($token) : (null === $token || $this->trustResolver->isAnonymous($token)); + if ($notAuthenticated) { if ($request->hasPreviousSession()) { $session->remove($this->sessionKey); } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index 78a8ecbf3cf91..32a5ca2573673 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -63,7 +63,7 @@ public function testUserProvidersNeedToImplementAnInterface() public function testOnKernelResponseWillAddSession() { $session = $this->runSessionOnKernelResponse( - new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit'), + new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit', ['ROLE_USER']), null ); @@ -75,7 +75,7 @@ public function testOnKernelResponseWillAddSession() public function testOnKernelResponseWillReplaceSession() { $session = $this->runSessionOnKernelResponse( - new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit'), + new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit', ['ROLE_USER']), 'C:10:"serialized"' ); @@ -107,7 +107,7 @@ public function testOnKernelResponseWillRemoveSessionOnAnonymousToken() public function testOnKernelResponseWithoutSession() { $tokenStorage = new TokenStorage(); - $tokenStorage->setToken(new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit')); + $tokenStorage->setToken(new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit', ['ROLE_USER'])); $request = new Request(); $request->attributes->set('_security_firewall_run', '_security_session'); $session = new Session(new MockArraySessionStorage());