Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Security] Deprecated AuthenticationTrustResolver #35860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,31 @@
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\Authorization\AuthorizationChecker;

/**
* The default implementation of the authentication trust resolver.
*
* @author Johannes M. Schmitt <[email protected]>
*
* @deprecated since symfony/security-core 5.1
*/
class AuthenticationTrustResolver implements AuthenticationTrustResolverInterface
{
public function __construct(bool $triggerDeprecation = true)
{
if ($triggerDeprecation) {
trigger_deprecation('symfony/security-core', '5.1', '%s is deprecated.', __CLASS__);
}
}

/**
* {@inheritdoc}
*/
public function isAnonymous(TokenInterface $token = null)
{
trigger_deprecation('symfony/security-core', '5.1', 'The %s is deprecated, use %s::isGranted("IS_ANONYMOUS") instead.', __CLASS__, AuthorizationChecker::class);

if (null === $token) {
return false;
}
Expand All @@ -39,6 +51,8 @@ public function isAnonymous(TokenInterface $token = null)
*/
public function isRememberMe(TokenInterface $token = null)
{
trigger_deprecation('symfony/security-core', '5.1', 'The %s is deprecated, use %s::isGranted("IS_REMEMBERED") instead.', __CLASS__, AuthorizationChecker::class);

if (null === $token) {
return false;
}
Expand All @@ -51,6 +65,8 @@ public function isRememberMe(TokenInterface $token = null)
*/
public function isFullFledged(TokenInterface $token = null)
{
trigger_deprecation('symfony/security-core', '5.1', 'The %s is deprecated, use %s::isGranted("IS_AUTHENTICATED_FULLY") instead.', __CLASS__, AuthorizationChecker::class);

if (null === $token) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* Interface for resolving the authentication status of a given token.
*
* @author Johannes M. Schmitt <[email protected]>
*
* @deprecated since symfony/security-core 5.1
*/
interface AuthenticationTrustResolverInterface
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
namespace Symfony\Component\Security\Core\Authorization\Voter;

use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverTrait;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

Expand All @@ -35,9 +38,13 @@ class AuthenticatedVoter implements VoterInterface

private $authenticationTrustResolver;

public function __construct(AuthenticationTrustResolverInterface $authenticationTrustResolver)
public function __construct(AuthenticationTrustResolverInterface $authenticationTrustResolver = null)
{
$this->authenticationTrustResolver = $authenticationTrustResolver;
if (null !== $authenticationTrustResolver) {
trigger_deprecation('symfony/security-core', '5.1', 'Passing instance of "%s" as first argument to "%s" is deprecated.', AuthenticationTrustResolverInterface::class, __CLASS__);

$this->authenticationTrustResolver = $authenticationTrustResolver;
}
}

/**
Expand All @@ -46,6 +53,7 @@ public function __construct(AuthenticationTrustResolverInterface $authentication
public function vote(TokenInterface $token, $subject, array $attributes)
{
$result = VoterInterface::ACCESS_ABSTAIN;

foreach ($attributes as $attribute) {
if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute
&& self::IS_AUTHENTICATED_REMEMBERED !== $attribute
Expand All @@ -57,30 +65,33 @@ public function vote(TokenInterface $token, $subject, array $attributes)
}

$result = VoterInterface::ACCESS_DENIED;
if (null === $token) {
return $result;
}

if (self::IS_AUTHENTICATED_FULLY === $attribute
&& $this->authenticationTrustResolver->isFullFledged($token)) {
&& (null !== $this->authenticationTrustResolver ? $this->authenticationTrustResolver->isFullFledged($token) : $this->isFullyFledged($token))) {
return VoterInterface::ACCESS_GRANTED;
}

if (self::IS_AUTHENTICATED_REMEMBERED === $attribute
&& ($this->authenticationTrustResolver->isRememberMe($token)
|| $this->authenticationTrustResolver->isFullFledged($token))) {
&& (null !== $this->authenticationTrustResolver ? ($this->authenticationTrustResolver->isRememberMe($token)
|| $this->authenticationTrustResolver->isFullFledged($token)) : ($token instanceof RememberMeToken || $this->isFullyFledged($token)))) {
return VoterInterface::ACCESS_GRANTED;
}

if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute
&& ($this->authenticationTrustResolver->isAnonymous($token)
&& (null !== $this->authenticationTrustResolver ? ($this->authenticationTrustResolver->isAnonymous($token)
|| $this->authenticationTrustResolver->isRememberMe($token)
|| $this->authenticationTrustResolver->isFullFledged($token))) {
|| $this->authenticationTrustResolver->isFullFledged($token)) : ($token instanceof AnonymousToken || $token instanceof RememberMeToken || $this->isFullyFledged($token)))) {
return VoterInterface::ACCESS_GRANTED;
}

if (self::IS_REMEMBERED === $attribute && $this->authenticationTrustResolver->isRememberMe($token)) {
if (self::IS_REMEMBERED === $attribute && (null !== $this->authenticationTrustResolver ? $this->authenticationTrustResolver->isRememberMe($token) : $token instanceof RememberMeToken)) {
return VoterInterface::ACCESS_GRANTED;
}

if (self::IS_ANONYMOUS === $attribute && $this->authenticationTrustResolver->isAnonymous($token)) {
if (self::IS_ANONYMOUS === $attribute && (null !== $this->authenticationTrustResolver ? $this->authenticationTrustResolver->isAnonymous($token) : $token instanceof AnonymousToken)) {
return VoterInterface::ACCESS_GRANTED;
}

Expand All @@ -91,4 +102,9 @@ public function vote(TokenInterface $token, $subject, array $attributes)

return $result;
}

private function isFullyFledged(TokenInterface $token): bool
{
return !$token instanceof AnonymousToken && !$token instanceof RememberMeToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
Expand All @@ -31,8 +32,28 @@ class ExpressionVoter implements VoterInterface
private $authChecker;
private $roleHierarchy;

public function __construct(ExpressionLanguage $expressionLanguage, AuthenticationTrustResolverInterface $trustResolver, AuthorizationCheckerInterface $authChecker, RoleHierarchyInterface $roleHierarchy = null)
public function __construct(ExpressionLanguage $expressionLanguage, /*AuthenticationTrustResolverInterface */$trustResolver, /*AuthorizationCheckerInterface */$authChecker = null, /*RoleHierarchyInterface */$roleHierarchy = null)
{
// $expr, $trust, $auth, ?$role
// $expr, $auth, ?$role
if ($trustResolver instanceof AuthenticationTrustResolverInterface) {
// old signature
trigger_deprecation('symfony/security-core', '5.1', 'Passing an %s as second argument to %s is deprecated.', AuthenticationTrustResolverInterface::class, __CLASS__);
} else {
// new signature: ExpressionLanguage $expressionLanguage, AuthorizationCheckerInterface $authChecker, RoleHierarchyInterface $roleHierarchy = null
$roleHierarchy = $authChecker;
$authChecker = $trustResolver;
$trustResolver = new AuthenticationTrustResolver(false);
}

if (!$authChecker instanceof AuthorizationCheckerInterface) {
throw new \InvalidArgumentException(sprintf('Argument 2 of %s must be an instance of %s, %s given.', __METHOD__, AuthorizationCheckerInterface::class, is_object($authChecker) ? get_class($authChecker) : gettype($authChecker)));
}

if (null !== $roleHierarchy && !$roleHierarchy instanceof RoleHierarchyInterface) {
throw new \InvalidArgumentException(sprintf('Argument 3 of %s must be an instance of %s or null, %s given.', __METHOD__, RoleHierarchyInterface::class, is_object($roleHierarchy) ? get_class($roleHierarchy) : gettype($roleHierarchy)));
}

$this->expressionLanguage = $expressionLanguage;
$this->trustResolver = $trustResolver;
$this->authChecker = $authChecker;
Expand Down
19 changes: 16 additions & 3 deletions src/Symfony/Component/Security/Http/Firewall/ContextListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,21 @@ class ContextListener extends AbstractListener
/**
* @param iterable|UserProviderInterface[] $userProviders
*/
public function __construct(TokenStorageInterface $tokenStorage, iterable $userProviders, string $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null, callable $sessionTrackerEnabler = null)
public function __construct(TokenStorageInterface $tokenStorage, iterable $userProviders, string $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, /*AuthenticationTrustResolverInterface */$trustResolver = null, callable $sessionTrackerEnabler = null)
{
if ($trustResolver instanceof AuthenticationTrustResolverInterface) {
// old signature
trigger_deprecation('symfony/security-core', '5.1', 'Passing an %s as second argument to %s is deprecated.', AuthenticationTrustResolverInterface::class, __CLASS__);
} else {
// new signature
$sessionTrackerEnabler = $trustResolver;
$trustResolver = null;
}

if (null !== $sessionTrackerEnabler && !is_callable($sessionTrackerEnabler)) {
throw new \InvalidArgumentException(sprintf('Argument 2 of %s must be a callable, %s given.', __METHOD__, is_object($sessionTrackerEnabler) ? get_class($sessionTrackerEnabler) : gettype($sessionTrackerEnabler)));
}

if (empty($contextKey)) {
throw new \InvalidArgumentException('$contextKey must not be empty.');
}
Expand All @@ -69,7 +82,7 @@ public function __construct(TokenStorageInterface $tokenStorage, iterable $userP
$this->logger = $logger;
$this->dispatcher = class_exists(Event::class) ? LegacyEventDispatcherProxy::decorate($dispatcher) : $dispatcher;

$this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class);
$this->trustResolver = $trustResolver;
$this->sessionTrackerEnabler = $sessionTrackerEnabler;
}

Expand Down Expand Up @@ -166,7 +179,7 @@ public function onKernelResponse(ResponseEvent $event)
$usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : null;
$token = $this->tokenStorage->getToken();

if (null === $token || $this->trustResolver->isAnonymous($token)) {
if (null === $token || (null !== $this->trustResolver ? $this->trustResolver->isAnonymous($token) : (null !== $token && $token instanceof AnonymousToken))) {
if ($request->hasPreviousSession()) {
$session->remove($this->sessionKey);
}
Expand Down
48 changes: 46 additions & 2 deletions src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
Expand Down Expand Up @@ -56,8 +59,44 @@ class ExceptionListener
private $httpUtils;
private $stateless;

public function __construct(TokenStorageInterface $tokenStorage, AuthenticationTrustResolverInterface $trustResolver, HttpUtils $httpUtils, string $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint = null, string $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null, bool $stateless = false)
public function __construct(TokenStorageInterface $tokenStorage, /*AuthenticationTrustResolverInterface */$trustResolver, /*HttpUtils */$httpUtils, /*string */$providerKey = null, /*AuthenticationEntryPointInterface */$authenticationEntryPoint = null, /*string */$errorPage = null, /*AccessDeniedHandlerInterface */$accessDeniedHandler = null, /*LoggerInterface */$logger = null, /*bool */$stateless = false)
{
if ($trustResolver instanceof AuthenticationTrustResolverInterface) {
// old signature
trigger_deprecation('symfony/security-core', '5.1', 'Passing an %s as second argument to %s is deprecated.', AuthenticationTrustResolverInterface::class, __CLASS__);
} else {
// new signature
$stateless = $logger ?? false;
$logger = $accessDeniedHandler;
$accessDeniedHandler = $errorPage;
$errorPage = $authenticationEntryPoint;
$authenticationEntryPoint = $providerKey;
$providerKey = $httpUtils;
$httpUtils = $trustResolver;
}

if (!$httpUtils instanceof HttpUtils) {
throw new \InvalidArgumentException(sprintf('Argument 2 of %s must be an instance of %s, %s given.', __METHOD__, HttpUtils::class, is_object($httpUtils) ? get_class($httpUtils) : gettype($httpUtils)));
}
if (!\is_string($providerKey)) {
throw new \InvalidArgumentException(sprintf('Argument 3 of %s must be a string, %s given.', __METHOD__, is_object($providerKey) ? get_class($providerKey) : gettype($providerKey)));
}
if (null !== $authenticationEntryPoint && !$authenticationEntryPoint instanceof AuthenticationEntryPointInterface) {
throw new \InvalidArgumentException(sprintf('Argument 4 of %s must be an instance of %s, %s given.', __METHOD__, AuthenticationEntryPointInterface::class, is_object($authenticationEntryPoint) ? get_class($authenticationEntryPoint) : gettype($authenticationEntryPoint)));
}
if (null !== $errorPage && !\is_string($errorPage)) {
throw new \InvalidArgumentException(sprintf('Argument 5 of %s must be a string, %s given.', __METHOD__, is_object($errorPage) ? get_class($errorPage) : gettype($errorPage)));
}
if (null !== $accessDeniedHandler && !$accessDeniedHandler instanceof AccessDeniedHandlerInterface) {
throw new \InvalidArgumentException(sprintf('Argument 6 of %s must be an instance of %s, %s given.', __METHOD__, AccessDeniedHandlerInterface::class, is_object($accessDeniedHandler) ? get_class($accessDeniedHandler) : gettype($accessDeniedHandler)));
}
if (null !== $logger && !$logger instanceof LoggerInterface) {
throw new \InvalidArgumentException(sprintf('Argument 7 of %s must be an instance of %s, %s given.', __METHOD__, LoggerInterface::class, is_object($logger) ? get_class($logger) : gettype($logger)));
}
if (!\is_bool($stateless)) {
throw new \InvalidArgumentException(sprintf('Argument 8 of %s must be a boolean, %s given.', __METHOD__, is_object($stateless) ? get_class($stateless) : gettype($stateless)));
}

$this->tokenStorage = $tokenStorage;
$this->accessDeniedHandler = $accessDeniedHandler;
$this->httpUtils = $httpUtils;
Expand Down Expand Up @@ -137,7 +176,7 @@ private function handleAccessDeniedException(ExceptionEvent $event, AccessDenied
$event->setThrowable(new AccessDeniedHttpException($exception->getMessage(), $exception));

$token = $this->tokenStorage->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (!$this->isFullFledged($token)) {
if (null !== $this->logger) {
$this->logger->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', ['exception' => $exception]);
}
Expand Down Expand Up @@ -181,6 +220,11 @@ private function handleAccessDeniedException(ExceptionEvent $event, AccessDenied
}
}

private function isFullFledged(?TokenInterface $token): bool
{
return null !== $this->authenticationTrustResolver ? $this->authenticationTrustResolver->isFullFledged($token) : (null !== $token && !$token instanceof RememberMeToken && !$token instanceof AnonymousToken);
}

private function handleLogoutException(LogoutException $exception): void
{
if (null !== $this->logger) {
Expand Down
Loading