diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md index 23982ef159..b5f7f022aa 100644 --- a/UPGRADE-4.2.md +++ b/UPGRADE-4.2.md @@ -5,3 +5,16 @@ Security -------- * Using the `has_role()` function in security expressions is deprecated, use the `is_granted()` function instead. + * Passing custom class names to the + `Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver` to define + custom anonymous and remember me token classes is deprecated. To + use custom tokens, extend the existing `Symfony\Component\Security\Core\Authentication\Token\AnonymousToken` + or `Symfony\Component\Security\Core\Authentication\Token\RememberMeToken`. + +SecurityBundle +-------------- + + * Using the `security.authentication.trust_resolver.anonymous_class` and + `security.authentication.trust_resolver.rememberme_class` parameters to define + the token classes is deprecated. To use + custom tokens extend the existing AnonymousToken and RememberMeToken. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 61b7237b44..66ae66c172 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -78,6 +78,7 @@ Security * The `ContextListener::setLogoutOnUserChange()` method has been removed. * The `Symfony\Component\Security\Core\User\AdvancedUserInterface` has been removed. * The `ExpressionVoter::addExpressionLanguageProvider()` method has been removed. + * The `AuthenticationTrustResolver` constructor arguments have been removed. SecurityBundle -------------- @@ -85,6 +86,8 @@ SecurityBundle * The `logout_on_user_change` firewall option has been removed. * The `switch_user.stateless` firewall option has been removed. * The `SecurityUserValueResolver` class has been removed. + * The `security.authentication.trust_resolver.anonymous_class` parameter has been removed. + * The `security.authentication.trust_resolver.rememberme_class` parameter has been removed. Translation ----------- diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md index 648189bb15..32b9f618ad 100644 --- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -1,6 +1,15 @@ CHANGELOG ========= +4.2.0 +----- + + * Using the `security.authentication.trust_resolver.anonymous_class` and + `security.authentication.trust_resolver.rememberme_class` parameters to define + the token classes is deprecated. To use + custom tokens extend the existing `Symfony\Component\Security\Core\Authentication\Token\AnonymousToken` + or `Symfony\Component\Security\Core\Authentication\Token\RememberMeToken`. + 4.1.0 ----- diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 65c48e0855..a9d81bc417 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -5,8 +5,8 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Component\Security\Core\Authentication\Token\AnonymousToken - Symfony\Component\Security\Core\Authentication\Token\RememberMeToken + null + null diff --git a/src/Symfony/Component/Security/CHANGELOG.md b/src/Symfony/Component/Security/CHANGELOG.md index 87939e3a26..9348d1f38f 100644 --- a/src/Symfony/Component/Security/CHANGELOG.md +++ b/src/Symfony/Component/Security/CHANGELOG.md @@ -6,6 +6,11 @@ CHANGELOG * added the `is_granted()` function in security expressions * deprecated the `has_role()` function in security expressions, use `is_granted()` instead +* Passing custom class names to the + `Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver` to define + custom anonymous and remember me token classes is deprecated. To + use custom tokens, extend the existing `Symfony\Component\Security\Core\Authentication\Token\AnonymousToken` + or `Symfony\Component\Security\Core\Authentication\Token\RememberMeToken`. 4.1.0 ----- diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php index da7c34e586..cba6a87082 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Authentication; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; /** @@ -23,10 +25,18 @@ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterfac private $anonymousClass; private $rememberMeClass; - public function __construct(string $anonymousClass, string $rememberMeClass) + public function __construct(?string $anonymousClass = null, ?string $rememberMeClass = null) { $this->anonymousClass = $anonymousClass; $this->rememberMeClass = $rememberMeClass; + + if (null !== $anonymousClass && !is_a($anonymousClass, AnonymousToken::class, true)) { + @trigger_error(sprintf('Configuring a custom anonymous token class is deprecated since Symfony 4.2; have the "%s" class extend the "%s" class instead, and remove the "%s" constructor argument.', $anonymousClass, AnonymousToken::class, self::class), E_USER_DEPRECATED); + } + + if (null !== $rememberMeClass && !is_a($rememberMeClass, RememberMeToken::class, true)) { + @trigger_error(sprintf('Configuring a custom remember me token class is deprecated since Symfony 4.2; have the "%s" class extend the "%s" class instead, and remove the "%s" constructor argument.', $rememberMeClass, RememberMeToken::class, self::class), E_USER_DEPRECATED); + } } /** @@ -38,7 +48,11 @@ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterfac return false; } - return $token instanceof $this->anonymousClass; + if (null !== $this->anonymousClass) { + return $token instanceof $this->anonymousClass; + } + + return $token instanceof AnonymousToken; } /** @@ -50,7 +64,11 @@ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterfac return false; } - return $token instanceof $this->rememberMeClass; + if (null !== $this->rememberMeClass) { + return $token instanceof $this->rememberMeClass; + } + + return $token instanceof RememberMeToken; } /** diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php index 55ca05b43b..fb5a885161 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php @@ -13,10 +13,82 @@ namespace Symfony\Component\Security\Core\Tests\Authentication; use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class AuthenticationTrustResolverTest extends TestCase { public function testIsAnonymous() + { + $resolver = new AuthenticationTrustResolver(); + $this->assertFalse($resolver->isAnonymous(null)); + $this->assertFalse($resolver->isAnonymous($this->getToken())); + $this->assertFalse($resolver->isAnonymous($this->getRememberMeToken())); + $this->assertFalse($resolver->isAnonymous(new FakeCustomToken())); + $this->assertTrue($resolver->isAnonymous(new RealCustomAnonymousToken())); + $this->assertTrue($resolver->isAnonymous($this->getAnonymousToken())); + } + + public function testIsRememberMe() + { + $resolver = new AuthenticationTrustResolver(); + + $this->assertFalse($resolver->isRememberMe(null)); + $this->assertFalse($resolver->isRememberMe($this->getToken())); + $this->assertFalse($resolver->isRememberMe($this->getAnonymousToken())); + $this->assertFalse($resolver->isRememberMe(new FakeCustomToken())); + $this->assertTrue($resolver->isRememberMe(new RealCustomRememberMeToken())); + $this->assertTrue($resolver->isRememberMe($this->getRememberMeToken())); + } + + public function testisFullFledged() + { + $resolver = new AuthenticationTrustResolver(); + + $this->assertFalse($resolver->isFullFledged(null)); + $this->assertFalse($resolver->isFullFledged($this->getAnonymousToken())); + $this->assertFalse($resolver->isFullFledged($this->getRememberMeToken())); + $this->assertFalse($resolver->isFullFledged(new RealCustomAnonymousToken())); + $this->assertFalse($resolver->isFullFledged(new RealCustomRememberMeToken())); + $this->assertTrue($resolver->isFullFledged($this->getToken())); + $this->assertTrue($resolver->isFullFledged(new FakeCustomToken())); + } + + /** + * @group legacy + * @expectedDeprecation Configuring a custom anonymous token class is deprecated since Symfony 4.2; have the "Symfony\Component\Security\Core\Tests\Authentication\FakeCustomToken" class extend the "Symfony\Component\Security\Core\Authentication\Token\AnonymousToken" class instead, and remove the "Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver" constructor argument. + */ + public function testsAnonymousDeprecationWithCustomClasses() + { + $resolver = new AuthenticationTrustResolver(FakeCustomToken::class); + + $this->assertTrue($resolver->isAnonymous(new FakeCustomToken())); + } + + /** + * @group legacy + * @expectedDeprecation Configuring a custom remember me token class is deprecated since Symfony 4.2; have the "Symfony\Component\Security\Core\Tests\Authentication\FakeCustomToken" class extend the "Symfony\Component\Security\Core\Authentication\Token\RememberMeToken" class instead, and remove the "Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver" constructor argument. + */ + public function testIsRememberMeDeprecationWithCustomClasses() + { + $resolver = new AuthenticationTrustResolver(null, FakeCustomToken::class); + + $this->assertTrue($resolver->isRememberMe(new FakeCustomToken())); + } + + /** + * @group legacy + * @expectedDeprecation Configuring a custom remember me token class is deprecated since Symfony 4.2; have the "Symfony\Component\Security\Core\Tests\Authentication\FakeCustomToken" class extend the "Symfony\Component\Security\Core\Authentication\Token\RememberMeToken" class instead, and remove the "Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver" constructor argument. + */ + public function testIsFullFledgedDeprecationWithCustomClasses() + { + $resolver = new AuthenticationTrustResolver(FakeCustomToken::class, FakeCustomToken::class); + + $this->assertFalse($resolver->isFullFledged(new FakeCustomToken())); + } + + public function testIsAnonymousWithClassAsConstructorButStillExtending() { $resolver = $this->getResolver(); @@ -24,9 +96,10 @@ class AuthenticationTrustResolverTest extends TestCase $this->assertFalse($resolver->isAnonymous($this->getToken())); $this->assertFalse($resolver->isAnonymous($this->getRememberMeToken())); $this->assertTrue($resolver->isAnonymous($this->getAnonymousToken())); + $this->assertTrue($resolver->isAnonymous(new RealCustomAnonymousToken())); } - public function testIsRememberMe() + public function testIsRememberMeWithClassAsConstructorButStillExtending() { $resolver = $this->getResolver(); @@ -34,15 +107,18 @@ class AuthenticationTrustResolverTest extends TestCase $this->assertFalse($resolver->isRememberMe($this->getToken())); $this->assertFalse($resolver->isRememberMe($this->getAnonymousToken())); $this->assertTrue($resolver->isRememberMe($this->getRememberMeToken())); + $this->assertTrue($resolver->isRememberMe(new RealCustomRememberMeToken())); } - public function testisFullFledged() + public function testisFullFledgedWithClassAsConstructorButStillExtending() { $resolver = $this->getResolver(); $this->assertFalse($resolver->isFullFledged(null)); $this->assertFalse($resolver->isFullFledged($this->getAnonymousToken())); $this->assertFalse($resolver->isFullFledged($this->getRememberMeToken())); + $this->assertFalse($resolver->isFullFledged(new RealCustomAnonymousToken())); + $this->assertFalse($resolver->isFullFledged(new RealCustomRememberMeToken())); $this->assertTrue($resolver->isFullFledged($this->getToken())); } @@ -69,3 +145,84 @@ class AuthenticationTrustResolverTest extends TestCase ); } } + +class FakeCustomToken implements TokenInterface +{ + public function serialize() + { + } + + public function unserialize($serialized) + { + } + + public function __toString() + { + } + + public function getRoles() + { + } + + public function getCredentials() + { + } + + public function getUser() + { + } + + public function setUser($user) + { + } + + public function getUsername() + { + } + + public function isAuthenticated() + { + } + + public function setAuthenticated($isAuthenticated) + { + } + + public function eraseCredentials() + { + } + + public function getAttributes() + { + } + + public function setAttributes(array $attributes) + { + } + + public function hasAttribute($name) + { + } + + public function getAttribute($name) + { + } + + public function setAttribute($name, $value) + { + } +} + +class RealCustomAnonymousToken extends AnonymousToken +{ + public function __construct() + { + } +} + +class RealCustomRememberMeToken extends RememberMeToken +{ + public function __construct() + { + } +} diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php index 6c05ecfab5..7991715b7c 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php @@ -31,10 +31,8 @@ class ExpressionLanguageTest extends TestCase */ public function testIsAuthenticated($token, $expression, $result) { - $anonymousTokenClass = 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken'; - $rememberMeTokenClass = 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken'; $expressionLanguage = new ExpressionLanguage(); - $trustResolver = new AuthenticationTrustResolver($anonymousTokenClass, $rememberMeTokenClass); + $trustResolver = new AuthenticationTrustResolver(); $tokenStorage = new TokenStorage(); $tokenStorage->setToken($token); $accessDecisionManager = new AccessDecisionManager(array(new RoleVoter())); 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 1ba7e39163..0651526f49 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php @@ -23,7 +23,7 @@ class AuthenticatedVoterTest extends TestCase */ public function testVote($authenticated, $attributes, $expected) { - $voter = new AuthenticatedVoter($this->getResolver()); + $voter = new AuthenticatedVoter(new AuthenticationTrustResolver()); $this->assertSame($expected, $voter->vote($this->getToken($authenticated), null, $attributes)); } @@ -52,14 +52,6 @@ class AuthenticatedVoterTest extends TestCase ); } - protected function getResolver() - { - return new AuthenticationTrustResolver( - 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken', - 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken' - ); - } - protected function getToken($authenticated) { if ('fully' === $authenticated) {