Skip to content

Commit

Permalink
feature #26981 No more support for custom anon/remember tokens based …
Browse files Browse the repository at this point in the history
…on FQCN (Iltar van der Berg)

This PR was squashed before being merged into the 4.2-dev branch (closes #26981).

Discussion
----------

No more support for custom anon/remember tokens based on FQCN

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #26940
| License       | MIT
| Doc PR        | ~

This PR deprecates the ability to configure a custom anonymous and remember me token class, via the AuthenticationTrustResolver. The only change required _if_ you have changed the token classes like this, is to extend the Anonymous/RememberMe token classes.

Commits
-------

860d454 No more support for custom anon/remember tokens based on FQCN
  • Loading branch information
fabpot committed May 27, 2018
2 parents e077c79 + 860d454 commit f557f94
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 19 deletions.
9 changes: 9 additions & 0 deletions UPGRADE-4.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@ Security
* Using the `has_role()` function in security expressions is deprecated, use the `is_granted()` function instead.
* Not returning an array of 3 elements from `FirewallMapInterface::getListeners()` is deprecated, the 3rd element
must be an instance of `LogoutListener` or `null`.
* 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
--------------

* Passing a `FirewallConfig` instance as 3rd argument to the `FirewallContext` constructor is deprecated,
pass a `LogoutListener` instance instead.
* 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.
3 changes: 3 additions & 0 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Security
* The `ExpressionVoter::addExpressionLanguageProvider()` method has been removed.
* The `FirewallMapInterface::getListeners()` method must return an array of 3 elements,
the 3rd one must be either a `LogoutListener` instance or `null`.
* The `AuthenticationTrustResolver` constructor arguments have been removed.

SecurityBundle
--------------
Expand All @@ -89,6 +90,8 @@ SecurityBundle
* The `SecurityUserValueResolver` class has been removed.
* Passing a `FirewallConfig` instance as 3rd argument to the `FirewallContext` constructor
now throws a `\TypeError`, pass a `LogoutListener` instance instead.
* The `security.authentication.trust_resolver.anonymous_class` parameter has been removed.
* The `security.authentication.trust_resolver.rememberme_class` parameter has been removed.

Translation
-----------
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
-----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="security.authentication.trust_resolver.anonymous_class">Symfony\Component\Security\Core\Authentication\Token\AnonymousToken</parameter>
<parameter key="security.authentication.trust_resolver.rememberme_class">Symfony\Component\Security\Core\Authentication\Token\RememberMeToken</parameter>
<parameter key="security.authentication.trust_resolver.anonymous_class">null</parameter>
<parameter key="security.authentication.trust_resolver.rememberme_class">null</parameter>
<parameter key="security.role_hierarchy.roles" type="collection" />
</parameters>

Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Security/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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);
}
}

/**
Expand All @@ -38,7 +48,11 @@ public function isAnonymous(TokenInterface $token = null)
return false;
}

return $token instanceof $this->anonymousClass;
if (null !== $this->anonymousClass) {
return $token instanceof $this->anonymousClass;
}

return $token instanceof AnonymousToken;
}

/**
Expand All @@ -50,7 +64,11 @@ public function isRememberMe(TokenInterface $token = null)
return false;
}

return $token instanceof $this->rememberMeClass;
if (null !== $this->rememberMeClass) {
return $token instanceof $this->rememberMeClass;
}

return $token instanceof RememberMeToken;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,112 @@

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();

$this->assertFalse($resolver->isAnonymous(null));
$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();

$this->assertFalse($resolver->isRememberMe(null));
$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()));
}

Expand All @@ -69,3 +145,84 @@ protected function getResolver()
);
}
}

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()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -52,14 +52,6 @@ public function getVoteTests()
);
}

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) {
Expand Down

0 comments on commit f557f94

Please sign in to comment.