sonata-project / SonataAdminBundle

The missing Symfony Admin Generator
https://docs.sonata-project.org/projects/SonataAdminBundle
MIT License
2.11k stars 1.26k forks source link

The token storage contains no authentication token #6807

Closed lobodol closed 3 years ago

lobodol commented 3 years ago

Environment

Sonata packages

show

```bash composer show --latest 'sonata-project/*' ``` ``` sonata-project/admin-bundle 3.83.0 3.88.0 The missing Symfony Admin Generator sonata-project/block-bundle 4.4.0 4.5.0 Symfony SonataBlockBundle sonata-project/cache 2.0.1 2.1.0 Cache library sonata-project/doctrine-extensions 1.10.1 1.11.0 Doctrine2 behavioral extensions sonata-project/doctrine-orm-admin-bundle 3.26.0 3.27.0 Integrate Doctrine ORM into the SonataAdminBundle sonata-project/exporter 2.4.1 2.5.0 Lightweight Exporter library sonata-project/form-extensions 1.7.1 1.8.1 Symfony form extensions sonata-project/twig-extensions 1.4.2 1.5.0 Sonata twig extensions ```

Symfony packages

show

```bash composer show --latest 'symfony/*' ``` ``` symfony/apache-pack v1.0.1 v1.0.1 A pack for Apache support in Symfony symfony/asset v4.4.18 v5.2.1 Symfony Asset Component symfony/browser-kit v4.4.18 v5.2.1 Symfony BrowserKit Component symfony/cache v4.4.18 v5.2.1 Symfony Cache component with PSR-6, PSR-16, and tags symfony/cache-contracts v2.2.0 v2.2.0 Generic abstractions related to caching symfony/config v4.4.18 v5.2.1 Symfony Config Component symfony/console v4.4.18 v5.2.1 Symfony Console Component symfony/css-selector v4.4.18 v5.2.1 Symfony CssSelector Component symfony/debug v4.4.18 v4.4.18 Symfony Debug Component symfony/debug-bundle v4.4.18 v5.2.1 Symfony DebugBundle symfony/dependency-injection v4.4.18 v5.2.1 Symfony DependencyInjection Component symfony/deprecation-contracts v2.2.0 v2.2.0 A generic function and convention to trigger deprecation notices symfony/doctrine-bridge v4.4.18 v5.2.1 Symfony Doctrine Bridge symfony/dom-crawler v4.4.18 v5.2.1 Symfony DomCrawler Component symfony/dotenv v4.4.18 v5.2.1 Registers environment variables from a .env file symfony/error-handler v4.4.18 v5.2.1 Symfony ErrorHandler Component symfony/event-dispatcher v4.4.18 v5.2.1 Symfony EventDispatcher Component symfony/event-dispatcher-contracts v1.1.9 v2.2.0 Generic abstractions related to dispatching event symfony/expression-language v4.4.18 v5.2.1 Symfony ExpressionLanguage Component symfony/filesystem v4.4.18 v5.2.1 Symfony Filesystem Component symfony/finder v4.4.18 v5.2.1 Symfony Finder Component symfony/flex v1.11.0 v1.11.0 Composer plugin for Symfony symfony/form v4.4.18 v5.2.1 Symfony Form Component symfony/framework-bundle v4.4.18 v5.2.1 Symfony FrameworkBundle symfony/google-mailer v4.4.18 v5.2.1 Symfony Google Mailer Bridge symfony/http-client v4.4.18 v5.2.1 Symfony HttpClient component symfony/http-client-contracts v2.3.1 v2.3.1 Generic abstractions related to HTTP clients symfony/http-foundation v4.4.18 v5.2.1 Symfony HttpFoundation Component symfony/http-kernel v4.4.18 v5.2.1 Symfony HttpKernel Component symfony/inflector v4.4.18 v5.2.1 Symfony Inflector Component symfony/intl v4.4.18 v5.2.1 A PHP replacement layer for the C intl extension that includes additional d... symfony/mailer v4.4.18 v5.2.1 Symfony Mailer Component symfony/maker-bundle 1.27.0 v1.28.0 Symfony Maker helps you create empty commands, controllers, form classes, t... symfony/mime v4.4.18 v5.2.1 A library to manipulate MIME messages symfony/monolog-bridge v4.4.18 v5.2.1 Symfony Monolog Bridge symfony/monolog-bundle v3.6.0 v3.6.0 Symfony MonologBundle symfony/options-resolver v4.4.18 v5.2.1 Symfony OptionsResolver Component symfony/phpunit-bridge v5.2.1 v5.2.1 Symfony PHPUnit Bridge symfony/polyfill-intl-grapheme v1.20.0 v1.22.0 Symfony polyfill for intl's grapheme_* functions symfony/polyfill-intl-icu v1.20.0 v1.22.0 Symfony polyfill for intl's ICU-related data and classes symfony/polyfill-intl-idn v1.20.0 v1.22.0 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions symfony/polyfill-intl-normalizer v1.20.0 v1.22.0 Symfony polyfill for intl's Normalizer class and related functions symfony/polyfill-mbstring v1.20.0 v1.22.0 Symfony polyfill for the Mbstring extension symfony/polyfill-php72 v1.20.0 v1.22.0 Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions symfony/polyfill-php73 v1.20.0 v1.22.0 Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions symfony/polyfill-php80 v1.20.0 v1.22.0 Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions symfony/process v4.4.18 v5.2.1 Symfony Process Component symfony/property-access v4.4.18 v5.2.1 Symfony PropertyAccess Component symfony/property-info v4.4.18 v5.2.1 Symfony Property Info Component symfony/proxy-manager-bridge v4.4.18 v5.2.1 Symfony ProxyManager Bridge symfony/routing v4.4.18 v5.2.1 Symfony Routing Component symfony/security-acl v3.1.0 v3.1.1 Symfony Security Component - ACL (Access Control List) symfony/security-bundle v4.4.18 v5.2.1 Symfony SecurityBundle symfony/security-core v4.4.18 v5.2.1 Symfony Security Component - Core Library symfony/security-csrf v4.4.18 v5.2.1 Symfony Security Component - CSRF Library symfony/security-guard v4.4.18 v5.2.1 Symfony Security Component - Guard symfony/security-http v4.4.18 v5.2.1 Symfony Security Component - HTTP Integration symfony/serializer v4.4.18 v5.2.1 Symfony Serializer Component symfony/service-contracts v2.2.0 v2.2.0 Generic abstractions related to writing services symfony/stopwatch v4.4.18 v5.2.1 Symfony Stopwatch Component symfony/string v5.2.1 v5.2.1 Symfony String component symfony/swiftmailer-bundle v3.5.1 v3.5.2 Symfony SwiftmailerBundle symfony/templating v4.4.18 v5.2.1 Symfony Templating Component symfony/translation v4.4.18 v5.2.1 Symfony Translation Component symfony/translation-contracts v2.3.0 v2.3.0 Generic abstractions related to translation symfony/twig-bridge v4.4.18 v5.2.1 Symfony Twig Bridge symfony/twig-bundle v4.4.18 v5.2.1 Symfony TwigBundle symfony/validator v4.4.18 v5.2.1 Symfony Validator Component symfony/var-dumper v4.4.18 v5.2.1 Symfony mechanism for exploring and dumping PHP variables symfony/var-exporter v4.4.18 v5.2.1 A blend of var_export() + serialize() to turn any serializable data structu... symfony/web-link v4.4.18 v5.2.1 Symfony WebLink Component symfony/web-profiler-bundle v4.4.18 v5.2.1 Symfony WebProfilerBundle symfony/webpack-encore-bundle v1.8.0 v1.9.0 Integration with your Symfony app & Webpack Encore! symfony/yaml v4.4.18 v5.2.1 Symfony Yaml Component ```

PHP version

php -v
PHP 7.4.13 (cli) (built: Dec 11 2020 08:31:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.13, Copyright (c), by Zend Technologies
    with Xdebug v3.0.2, Copyright (c) 2002-2021, by Derick Rethans

Subject

Here is my ArticleAdmin class where I injected the service AuthorizationChecker in order to modify form building depending on user roles:

class ArticleAdmin extends AbstractAdmin {

    private AuthorizationChecker $authChecker;

    public function __construct($code, $class, $baseControllerName, AuthorizationChecker $authChecker) {
        $this->authChecker = $authChecker;
        parent::__construct($code, $class, $baseControllerName);
    }

    protected function configureFormFields(FormMapper $formMapper) {
        if ($this->authChecker->isGranted('ROLE_ADMIN')) {
            // Do stuff here...
        }
    }
}

And here are the relevent parts of the security.yaml file:

security:
    firewalls:
        main:
            pattern: ^/
            anonymous: true
            provider: main
    access_control:
        - { path: ^/admin, roles: [ROLE_SONATA_ADMIN, ROLE_BACK_OFFICE_ACCESS] }

And here the relevant parts of services.yaml:

    admin.article:
        class: App\Admin\ArticleAdmin
        arguments:
            - ~
            - App\Entity\Article
            - App\Controller\ArticleAdminController
            - '@security.authorization_checker'
        tags:
            - { name: sonata.admin, manager_type: orm, label: "Articles" }

Steps to reproduce

Just run the following command:

bin/console translation:update fr --force

Expected results

I expect translations to be extracted without any error.

Actual results

In AuthorizationChecker.php line 49:

  The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this   
  URL.

When I comment the line $this->authChecker->isGranted('ROLE_ADMIN') the error disappears.

franmomu commented 3 years ago

Hi @lobodol, I think this might not be a sonata issue, please take a look at this: https://github.com/symfony/symfony/issues/13635

lobodol commented 3 years ago

Hi @franmomu, it's weird because I use AuthorizationChecker::isGranted() nearly everywhere in my application and I had no problem elsewhere than in the Sonata admin class.
In addition, this problem appeared when I upgraded my project from Symfony 3.4 to Symfony 4.4 (and admin-bundle 3.57.0 -> 3.83.0). I had no problem before.

lobodol commented 3 years ago

I just tried to create a fresh new project with the minimum relevant components and let Flex run recipes:

symfony new sonata --version=lts
cd sonata
composer require sonata-project/admin-bundle
composer require sonata-project/admin-bundle
composer require symfony/web-server-bundle --dev
composer require symfony/maker-bundle --dev
composer require sonata-project/doctrine-orm-admin-bundle

Then I create a dummy entity:

bin/console make:entity Pizza

Then, update database:

bin/console doctrine:database:create
bin/console doctrine:schema:update --force

I create an Admin class with the Auth checker service injected.

Finally, I run the translation update command:

bin/console translation:update fr --force

And I got the exact same error.

franmomu commented 3 years ago

Hi @franmomu, it's weird because I use AuthorizationChecker::isGranted() nearly everywhere in my application and I had no problem elsewhere than in the Sonata admin class. In addition, this problem appeared when I upgraded my project from Symfony 3.4 to Symfony 4.4 (and admin-bundle 3.57.0 -> 3.83.0). I had no problem before.

I meant, if you have read the link above, the problem is using AuthorizationChecker::isGranted() calling it in a command. Can you please try to use AuthorizationChecker::isGranted() in a command of your own? to see if you get the exact same error.

lobodol commented 3 years ago

I meant, if you have read the link above, the problem is using AuthorizationChecker::isGranted() calling it in a command. Can you please try to use AuthorizationChecker::isGranted() in a command of your own? to see if you get the exact same error.

Yes I understand that. Indeed, in a command of my own I got the same error when trying to call AuthorizationChecker::isGranted(). This is the behavior reflected by the issue you linked.

However, a sonata admin class is not supposed to be a command, right? So, there should not be a problem using AuthorizationChecker in it?

franmomu commented 3 years ago

The sonata service is called from a command when extracting translating messages. There is no problem using AuthorizationChecker anywhere, the problem is the isGranted method:

https://github.com/symfony/symfony/blob/945c7c590c5ca2a75a32c9e3d2ba0c6c7d883afe/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php#L41-L63

you have to be aware the AuthorizationChecker::isGranted() could:

@throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token, so is the user who has to deal with this behaviour.

Look at the is_granted twig function implementation:

https://github.com/symfony/symfony/blob/945c7c590c5ca2a75a32c9e3d2ba0c6c7d883afe/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php#L36-L51

I hope it makes sense.

VincentLanglet commented 3 years ago

@franmomu I think the issue is coming from the Sonata\AdminBundle\Translator\Extractor\AdminExtractor.

Can't we call TokenStorageInterface::setToken before working with admins ?

franmomu commented 3 years ago

@franmomu I think the issue is coming from the Sonata\AdminBundle\Translator\Extractor\AdminExtractor.

Can't we call TokenStorageInterface::setToken before working with admins ?

Yes, it's coming from there, but IMHO is the user who has to deal with the possible exception thrown by the method, another example: https://github.com/FriendsOfSymfony/FOSUserBundle/issues/2038.

VincentLanglet commented 3 years ago

Closing then