Skip to content
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

PreviewToolbarListener (TokenChecker) starts session - even if stateless Route/Firewall #6220

Closed
xprojects-de opened this issue Jul 17, 2023 · 24 comments · Fixed by #6331
Closed
Labels
Milestone

Comments

@xprojects-de
Copy link
Contributor

xprojects-de commented Jul 17, 2023

Affected version(s)

5.x

Description

Since symfony 6.3 an error is thrown when starting a session in stateless routes.
see: https://github.com/symfony/symfony/blob/431d32156c814fdc255be46445032ca612e908dc/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php#L213

Since Symfony 6.3, routes are automatically defined as stateless if stateless is also defined in the firewall.
see: https://symfony.com/doc/current/reference/configuration/security.html#stateless

So if a valid backend session is active and you define a route or a firewall with, e.g. own scope and define it as stateless and dispatch an event in the Controller, an error occurs because the PreviewListener starts a session.

EDIT:
You can recreate this by doing a debug_backtrace in onSessionUsage() in DebugMode in Symfony\Component\HttpKernel\EventListener\AbstractSessionListene, defining the route as stateless and dispatch an event in your controller.
This happens, when you are logged into the Contao backend and use an API-Endpoint with stateless Route via a JS application under the same domain.

Actually it's not the PreviewToolbarListener itself but the token checker in the method hasBackendUser().
see:

if ($this->scopeMatcher->isBackendMainRequest($event) || !$this->tokenChecker->hasBackendUser()) {

So what do you think? Should be considered in the PreviewToolbarListener if routes are stateless? Otherwise it will be difficult to build stateless API endpoints...

Thanks and Greetings

@Toflar
Copy link
Member

Toflar commented Jul 17, 2023

Can you elaborate on your use case? What did you do to end up having that error. $this->scopeMatcher->isBackendMainRequest($event) should return false if _scope is not backend. Looks like you added _scope=backend on your own route and defined a stateless firewall for that? (which cannot work)

@fritzmg
Copy link
Contributor

fritzmg commented Jul 17, 2023

Where exactly is the session started? The TokenChecker does not start the session by itself either.

Which scope did your route have?

@xprojects-de
Copy link
Contributor Author

I have my own firewall with a scope.
see: https://github.com/xprojects-de/alpdesk-core/blob/771f00af8be9b2594e8215828f9c9ca3d90ff5a3/src/ContaoManager/Plugin.php#L67

The routes have the defined scope.
see: https://github.com/xprojects-de/alpdesk-core/blob/771f00af8be9b2594e8215828f9c9ca3d90ff5a3/src/Resources/config/routes.yml#L20

Here you can see the "StackTrace" as var_exp.

array (
  0 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/SessionBagProxy.php',
    'line' => 66,
    'function' => 'onSessionUsage',
    'class' => 'Symfony\\Component\\HttpKernel\\EventListener\\AbstractSessionListener',
    'type' => '->',
  ),
  1 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php',
    'line' => 443,
    'function' => 'initialize',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\SessionBagProxy',
    'type' => '->',
  ),
  2 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php',
    'line' => 176,
    'function' => 'loadSession',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
    'type' => '->',
  ),
  3 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php',
    'line' => 311,
    'function' => 'start',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
    'type' => '->',
  ),
  4 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Session.php',
    'line' => 222,
    'function' => 'getBag',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
    'type' => '->',
  ),
  5 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Session.php',
    'line' => 242,
    'function' => 'getBag',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Session',
    'type' => '->',
  ),
  6 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-foundation/Session/Session.php',
    'line' => 64,
    'function' => 'getAttributeBag',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Session',
    'type' => '->',
  ),
  7 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/contao/core-bundle/src/Security/Authentication/Token/TokenChecker.php',
    'line' => 199,
    'function' => 'has',
    'class' => 'Symfony\\Component\\HttpFoundation\\Session\\Session',
    'type' => '->',
  ),
  8 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/contao/core-bundle/src/Security/Authentication/Token/TokenChecker.php',
    'line' => 155,
    'function' => 'getTokenFromSession',
    'class' => 'Contao\\CoreBundle\\Security\\Authentication\\Token\\TokenChecker',
    'type' => '->',
  ),
  9 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/contao/core-bundle/src/Security/Authentication/Token/TokenChecker.php',
    'line' => 65,
    'function' => 'getToken',
    'class' => 'Contao\\CoreBundle\\Security\\Authentication\\Token\\TokenChecker',
    'type' => '->',
  ),
  10 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/contao/core-bundle/src/EventListener/PreviewToolbarListener.php',
    'line' => 47,
    'function' => 'hasBackendUser',
    'class' => 'Contao\\CoreBundle\\Security\\Authentication\\Token\\TokenChecker',
    'type' => '->',
  ),
  11 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/event-dispatcher/Debug/WrappedListener.php',
    'line' => 116,
    'function' => '__invoke',
    'class' => 'Contao\\CoreBundle\\EventListener\\PreviewToolbarListener',
    'type' => '->',
  ),
  12 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/event-dispatcher/EventDispatcher.php',
    'line' => 220,
    'function' => '__invoke',
    'class' => 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener',
    'type' => '->',
  ),
  13 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/event-dispatcher/EventDispatcher.php',
    'line' => 56,
    'function' => 'callListeners',
    'class' => 'Symfony\\Component\\EventDispatcher\\EventDispatcher',
    'type' => '->',
  ),
  14 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php',
    'line' => 139,
    'function' => 'dispatch',
    'class' => 'Symfony\\Component\\EventDispatcher\\EventDispatcher',
    'type' => '->',
  ),
  15 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-kernel/HttpKernel.php',
    'line' => 199,
    'function' => 'dispatch',
    'class' => 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher',
    'type' => '->',
  ),
  16 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-kernel/HttpKernel.php',
    'line' => 187,
    'function' => 'filterResponse',
    'class' => 'Symfony\\Component\\HttpKernel\\HttpKernel',
    'type' => '->',
  ),
  17 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-kernel/HttpKernel.php',
    'line' => 74,
    'function' => 'handleRaw',
    'class' => 'Symfony\\Component\\HttpKernel\\HttpKernel',
    'type' => '->',
  ),
  18 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/vendor/symfony/http-kernel/Kernel.php',
    'line' => 197,
    'function' => 'handle',
    'class' => 'Symfony\\Component\\HttpKernel\\HttpKernel',
    'type' => '->',
  ),
  19 => 
  array (
    'file' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/public/index.php',
    'line' => 44,
    'function' => 'handle',
    'class' => 'Symfony\\Component\\HttpKernel\\Kernel',
    'type' => '->',
  ),
)

@xprojects-de
Copy link
Contributor Author

Here the request as var_exp. There you can see the Route have the right scope...

Symfony\Component\HttpFoundation\Request::__set_state(array(
   'attributes' => 
  Symfony\Component\HttpFoundation\ParameterBag::__set_state(array(
     'parameters' => 
    array (
      '_stopwatch_token' => '308475',
      '_route' => 'alpdesk_auth_member',
      '_controller' => 'Alpdesk\\AlpdeskCore\\Controller\\Auth\\AlpdeskCoreAuthController::member',
      '_scope' => 'alpdeskapi',
      '_token_check' => false,
      '_route_params' => 
      array (
        '_scope' => 'alpdeskapi',
        '_token_check' => false,
      ),
      '_firewall_context' => 'security.firewall.map.context.alpdeskcore_api',
      '_stateless' => true,
    ),
  )),
   'request' => 
  Symfony\Component\HttpFoundation\InputBag::__set_state(array(
     'parameters' => 
    array (
    ),
  )),
   'query' => 
  Symfony\Component\HttpFoundation\InputBag::__set_state(array(
     'parameters' => 
    array (
    ),
  )),
   'server' => 
  Symfony\Component\HttpFoundation\ServerBag::__set_state(array(
     'parameters' => 
    array (
      'PHP_FCGI_CHILDREN' => '4',
      'PWD' => '/Applications/MAMP/fcgi-bin',
      'SHLVL' => '0',
      'PHP_FCGI_MAX_REQUESTS' => '200',
      '__CF_USER_TEXT_ENCODING' => '0x1F5:0x0:0x3',
      'ORIG_SCRIPT_NAME' => '/fcgi-bin/php8.1.17.fcgi',
      'ORIG_PATH_TRANSLATED' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/public/index.php',
      'ORIG_PATH_INFO' => '/index.php',
      'ORIG_SCRIPT_FILENAME' => '/Applications/MAMP/fcgi-bin/php8.1.17.fcgi',
      'SCRIPT_NAME' => '/index.php',
      'REQUEST_URI' => '/auth/member',
      'QUERY_STRING' => '',
      'REQUEST_METHOD' => 'POST',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
      'GATEWAY_INTERFACE' => 'CGI/1.1',
      'REDIRECT_URL' => '/index.php',
      'REMOTE_PORT' => '63813',
      'SCRIPT_FILENAME' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/public/index.php',
      'SERVER_ADMIN' => 'you@example.com',
      'CONTEXT_DOCUMENT_ROOT' => '/Applications/MAMP/fcgi-bin/',
      'CONTEXT_PREFIX' => '/fcgi-bin/',
      'REQUEST_SCHEME' => 'https',
      'DOCUMENT_ROOT' => '/Users/benjaminhummel/Documents/MAMPP/alpdesk-core/public',
      'REMOTE_ADDR' => '::1',
      'SERVER_PORT' => '8890',
      'SERVER_ADDR' => '::1',
      'SERVER_NAME' => 'alpdesk-core',
      'SERVER_SOFTWARE' => 'Apache/2.4.54 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141 OpenSSL/1.0.2u mod_wsgi/3.5 Python/2.7.18',
      'SERVER_SIGNATURE' => '',
      'PATH' => '/usr/bin:/bin:/usr/sbin:/sbin',
      'CONTENT_LENGTH' => '0',
      'HTTP_CACHE_CONTROL' => 'no-cache',
      'HTTP_PRAGMA' => 'no-cache',
      'HTTP_SEC_GPC' => '1',
      'HTTP_SEC_FETCH_SITE' => 'same-origin',
      'HTTP_SEC_FETCH_MODE' => 'cors',
      'HTTP_SEC_FETCH_DEST' => 'empty',
      'HTTP_COOKIE' => 'PHPSESSID=a5nsmm9ukmfc66coem7a3rjdkl; csrf_https-contao_csrf_token=20euvfTzzPxtpmWBFqx8rktGlCUqKmeijVd7mZ6jLtk',
      'HTTP_CONNECTION' => 'keep-alive',
      'HTTP_ORIGIN' => 'https://alpdesk-core:8890',
      'CONTENT_TYPE' => 'application/json',
      'HTTP_REFERER' => 'https://alpdesk-core:8890/alpdeskclient/login?rt=1689579877637',
      'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, br',
      'HTTP_ACCEPT_LANGUAGE' => 'de,en-US;q=0.7,en;q=0.3',
      'HTTP_ACCEPT' => 'application/json, text/plain, */*',
      'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0',
      'HTTP_HOST' => 'alpdesk-core:8890',
      'SSL_TLS_SNI' => 'alpdesk-core',
      'HTTPS' => 'on',
      'HTTP_AUTHORIZATION' => 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBbHBkZXNrIiwiYXVkIjoiaHR0cHM6Ly9hbHBkZXNrLmRlIiwianRpIjoiWVd4d1pHVnphMTlvYjIxbFlYVjBiMjFoZEdsdmJrZDFhUT09IiwiaWF0IjoxNjg5NTgwMDU2LCJuYmYiOjE2ODk1ODAwNTYsImV4cCI6MTY4OTYzNDA1NiwidXNlcm5hbWUiOiJob21lYXV0b21hdGlvbkd1aSJ9.o5d7j3wOeYariABJtHHAXJEfx0jBuz_DEscWshBdP5E',
      'REDIRECT_STATUS' => '200',
      'REDIRECT_HANDLER' => 'php-fastcgi',
      'REDIRECT_SSL_SESSION_RESUMED' => 'Initial',
      'REDIRECT_SSL_SERVER_A_SIG' => 'sha256WithRSAEncryption',
      'REDIRECT_SSL_SERVER_A_KEY' => 'rsaEncryption',
      'REDIRECT_SSL_SERVER_I_DN' => 'CN=MAMP_PRO_Root_CA,OU=MAMP PRO',
      'REDIRECT_SSL_SERVER_S_DN' => 'OU=6.7,CN=alpdesk-core,O=MAMP PRO',
      'REDIRECT_SSL_SERVER_V_END' => 'Jan 24 19:56:24 2024 GMT',
      'REDIRECT_SSL_SERVER_V_START' => 'Jan 24 19:56:24 2023 GMT',
      'REDIRECT_SSL_SERVER_M_SERIAL' => '98BA4352B89FDDB8',
      'REDIRECT_SSL_SERVER_M_VERSION' => '3',
      'REDIRECT_SSL_CLIENT_VERIFY' => 'NONE',
      'REDIRECT_SSL_CIPHER_ALGKEYSIZE' => '128',
      'REDIRECT_SSL_CIPHER_USEKEYSIZE' => '128',
      'REDIRECT_SSL_CIPHER_EXPORT' => 'false',
      'REDIRECT_SSL_CIPHER' => 'ECDHE-RSA-AES128-GCM-SHA256',
      'REDIRECT_SSL_COMPRESS_METHOD' => 'NULL',
      'REDIRECT_SSL_SECURE_RENEG' => 'true',
      'REDIRECT_SSL_PROTOCOL' => 'TLSv1.2',
      'REDIRECT_SSL_VERSION_LIBRARY' => 'OpenSSL/1.0.2u',
      'REDIRECT_SSL_VERSION_INTERFACE' => 'mod_ssl/2.4.54',
      'REDIRECT_SSL_SERVER_SAN_DNS_2' => 'contao.alpdesk-core',
      'REDIRECT_SSL_SERVER_SAN_DNS_1' => 'alpdesk-core.local',
      'REDIRECT_SSL_SERVER_SAN_DNS_0' => 'alpdesk-core',
      'REDIRECT_SSL_SERVER_I_DN_CN' => 'MAMP_PRO_Root_CA',
      'REDIRECT_SSL_SERVER_I_DN_OU' => 'MAMP PRO',
      'REDIRECT_SSL_SERVER_S_DN_OU' => '6.7',
      'REDIRECT_SSL_SERVER_S_DN_CN' => 'alpdesk-core',
      'REDIRECT_SSL_SERVER_S_DN_O' => 'MAMP PRO',
      'REDIRECT_SSL_TLS_SNI' => 'alpdesk-core',
      'REDIRECT_HTTPS' => 'on',
      'REDIRECT_HTTP_AUTHORIZATION' => 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBbHBkZXNrIiwiYXVkIjoiaHR0cHM6Ly9hbHBkZXNrLmRlIiwianRpIjoiWVd4d1pHVnphMTlvYjIxbFlYVjBiMjFoZEdsdmJrZDFhUT09IiwiaWF0IjoxNjg5NTgwMDU2LCJuYmYiOjE2ODk1ODAwNTYsImV4cCI6MTY4OTYzNDA1NiwidXNlcm5hbWUiOiJob21lYXV0b21hdGlvbkd1aSJ9.o5d7j3wOeYariABJtHHAXJEfx0jBuz_DEscWshBdP5E',
      'REDIRECT_REDIRECT_STATUS' => '200',
      'REDIRECT_REDIRECT_SSL_TLS_SNI' => 'alpdesk-core',
      'REDIRECT_REDIRECT_HTTPS' => 'on',
      'REDIRECT_REDIRECT_HTTP_AUTHORIZATION' => 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBbHBkZXNrIiwiYXVkIjoiaHR0cHM6Ly9hbHBkZXNrLmRlIiwianRpIjoiWVd4d1pHVnphMTlvYjIxbFlYVjBiMjFoZEdsdmJrZDFhUT09IiwiaWF0IjoxNjg5NTgwMDU2LCJuYmYiOjE2ODk1ODAwNTYsImV4cCI6MTY4OTYzNDA1NiwidXNlcm5hbWUiOiJob21lYXV0b21hdGlvbkd1aSJ9.o5d7j3wOeYariABJtHHAXJEfx0jBuz_DEscWshBdP5E',
      'FCGI_ROLE' => 'RESPONDER',
      'PHP_SELF' => '/index.php',
      'REQUEST_TIME_FLOAT' => 1689580056.521055,
      'REQUEST_TIME' => 1689580056,
    ),
  )),
   'files' => 
  Symfony\Component\HttpFoundation\FileBag::__set_state(array(
     'parameters' => 
    array (
    ),
  )),
   'cookies' => 
  Symfony\Component\HttpFoundation\InputBag::__set_state(array(
     'parameters' => 
    array (
      'PHPSESSID' => 'a5nsmm9ukmfc66coem7a3rjdkl',
      'csrf_https-contao_csrf_token' => '20euvfTzzPxtpmWBFqx8rktGlCUqKmeijVd7mZ6jLtk',
    ),
  )),
   'headers' => 
  Symfony\Component\HttpFoundation\HeaderBag::__set_state(array(
     'headers' => 
    array (
      'content-length' => 
      array (
        0 => '0',
      ),
      'cache-control' => 
      array (
        0 => 'no-cache',
      ),
      'pragma' => 
      array (
        0 => 'no-cache',
      ),
      'sec-gpc' => 
      array (
        0 => '1',
      ),
      'sec-fetch-site' => 
      array (
        0 => 'same-origin',
      ),
      'sec-fetch-mode' => 
      array (
        0 => 'cors',
      ),
      'sec-fetch-dest' => 
      array (
        0 => 'empty',
      ),
      'cookie' => 
      array (
        0 => 'PHPSESSID=a5nsmm9ukmfc66coem7a3rjdkl; csrf_https-contao_csrf_token=20euvfTzzPxtpmWBFqx8rktGlCUqKmeijVd7mZ6jLtk',
      ),
      'connection' => 
      array (
        0 => 'keep-alive',
      ),
      'origin' => 
      array (
        0 => 'https://alpdesk-core:8890',
      ),
      'content-type' => 
      array (
        0 => 'application/json',
      ),
      'referer' => 
      array (
        0 => 'https://alpdesk-core:8890/alpdeskclient/login?rt=1689579877637',
      ),
      'accept-encoding' => 
      array (
        0 => 'gzip, deflate, br',
      ),
      'accept-language' => 
      array (
        0 => 'de,en-US;q=0.7,en;q=0.3',
      ),
      'accept' => 
      array (
        0 => 'application/json, text/plain, */*',
      ),
      'user-agent' => 
      array (
        0 => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0',
      ),
      'host' => 
      array (
        0 => 'alpdesk-core:8890',
      ),
      'authorization' => 
      array (
        0 => 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBbHBkZXNrIiwiYXVkIjoiaHR0cHM6Ly9hbHBkZXNrLmRlIiwianRpIjoiWVd4d1pHVnphMTlvYjIxbFlYVjBiMjFoZEdsdmJrZDFhUT09IiwiaWF0IjoxNjg5NTgwMDU2LCJuYmYiOjE2ODk1ODAwNTYsImV4cCI6MTY4OTYzNDA1NiwidXNlcm5hbWUiOiJob21lYXV0b21hdGlvbkd1aSJ9.o5d7j3wOeYariABJtHHAXJEfx0jBuz_DEscWshBdP5E',
      ),
      'x-php-ob-level' => 
      array (
        0 => '1',
      ),
    ),
     'cacheControl' => 
    array (
      'no-cache' => true,
    ),
  )),
   'content' => '',
   'languages' => 
  array (
    0 => 'de',
    1 => 'en_US',
    2 => 'en',
  ),
   'charsets' => NULL,
   'encodings' => NULL,
   'acceptableContentTypes' => NULL,
   'pathInfo' => '/auth/member',
   'requestUri' => '/auth/member',
   'baseUrl' => '',
   'basePath' => NULL,
   'method' => 'POST',
   'format' => NULL,
   'session' => 
  Symfony\Component\HttpFoundation\Session\Session::__set_state(array(
     'storage' => 
    Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage::__set_state(array(
       'bags' => 
      array (
        'attributes' => 
        Symfony\Component\HttpFoundation\Session\SessionBagProxy::__set_state(array(
           'bag' => 
          Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag::__set_state(array(
             'name' => 'attributes',
             'storageKey' => '_sf2_attributes',
             'attributes' => 
            array (
              '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
              'referer' => 
              array (
                'IcASpCXx' => 
                array (
                  'last' => '',
                  'current' => '/contao',
                ),
              ),
            ),
          )),
           'data' => 
          array (
            '_sf2_attributes' => 
            array (
              '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
              'referer' => 
              array (
                'IcASpCXx' => 
                array (
                  'last' => '',
                  'current' => '/contao',
                ),
              ),
            ),
            '_symfony_flashes' => 
            array (
            ),
            '_contao_be_attributes' => 
            array (
              'fieldset_states' => 
              array (
                'tl_user' => 
                array (
                  'theme_legend' => 1,
                  'alpdeskcore_legend' => 1,
                ),
                'tl_settings' => 
                array (
                  'backend_legend' => 1,
                  'security_legend' => 1,
                  'files_legend' => 1,
                  'uploads_legend' => 1,
                ),
                'tl_member' => 
                array (
                  'homedir_legend' => 1,
                ),
                'tl_layout' => 
                array (
                  'jquery_legend' => 1,
                ),
                'tl_user_group' => 
                array (
                  'alexf_legend' => 1,
                  'alpdeskcore_legend' => 1,
                  'modules_legend' => 0,
                ),
              ),
              'new_records' => 
              array (
                'tl_theme' => 
                array (
                  0 => '1',
                ),
                'tl_layout' => 
                array (
                  0 => '1',
                ),
                'tl_alpdeskcore_sessions' => 
                array (
                  0 => '2',
                ),
                'tl_user_group' => 
                array (
                  0 => '1',
                ),
                'tl_user' => 
                array (
                  0 => '2',
                ),
                'tl_alpdeskcore_databasemanager' => 
                array (
                  0 => '2',
                ),
              ),
              'filetree' => 
              array (
                'c7c86130' => 1,
                '25eadaf9' => 1,
                'f45857ec' => 1,
                '5b5f7a49' => 1,
                'e7e45088' => 1,
              ),
              'tl_page_tree' => 
              array (
                1 => 1,
                2 => 0,
              ),
              'tl_article_tl_page_tree' => 
              array (
                1 => 0,
              ),
              'checkbox_groups' => 
              array (
                'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
                'cbc_modules_alpdesk-core' => 1,
                'cbc_modules_layout' => 1,
                'cbc_modules_benutzer' => 1,
                'cbc_modules_system' => 1,
              ),
            ),
            '_contao_fe_attributes' => 
            array (
            ),
          ),
           'usageIndex' => 6,
           'usageReporter' => 
          Closure::__set_state(array(
          )),
        )),
        'flashes' => 
        Symfony\Component\HttpFoundation\Session\SessionBagProxy::__set_state(array(
           'bag' => 
          Symfony\Component\HttpFoundation\Session\Flash\FlashBag::__set_state(array(
             'name' => 'flashes',
             'flashes' => 
            array (
            ),
             'storageKey' => '_symfony_flashes',
          )),
           'data' => 
          array (
            '_sf2_attributes' => 
            array (
              '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
              'referer' => 
              array (
                'IcASpCXx' => 
                array (
                  'last' => '',
                  'current' => '/contao',
                ),
              ),
            ),
            '_symfony_flashes' => 
            array (
            ),
            '_contao_be_attributes' => 
            array (
              'fieldset_states' => 
              array (
                'tl_user' => 
                array (
                  'theme_legend' => 1,
                  'alpdeskcore_legend' => 1,
                ),
                'tl_settings' => 
                array (
                  'backend_legend' => 1,
                  'security_legend' => 1,
                  'files_legend' => 1,
                  'uploads_legend' => 1,
                ),
                'tl_member' => 
                array (
                  'homedir_legend' => 1,
                ),
                'tl_layout' => 
                array (
                  'jquery_legend' => 1,
                ),
                'tl_user_group' => 
                array (
                  'alexf_legend' => 1,
                  'alpdeskcore_legend' => 1,
                  'modules_legend' => 0,
                ),
              ),
              'new_records' => 
              array (
                'tl_theme' => 
                array (
                  0 => '1',
                ),
                'tl_layout' => 
                array (
                  0 => '1',
                ),
                'tl_alpdeskcore_sessions' => 
                array (
                  0 => '2',
                ),
                'tl_user_group' => 
                array (
                  0 => '1',
                ),
                'tl_user' => 
                array (
                  0 => '2',
                ),
                'tl_alpdeskcore_databasemanager' => 
                array (
                  0 => '2',
                ),
              ),
              'filetree' => 
              array (
                'c7c86130' => 1,
                '25eadaf9' => 1,
                'f45857ec' => 1,
                '5b5f7a49' => 1,
                'e7e45088' => 1,
              ),
              'tl_page_tree' => 
              array (
                1 => 1,
                2 => 0,
              ),
              'tl_article_tl_page_tree' => 
              array (
                1 => 0,
              ),
              'checkbox_groups' => 
              array (
                'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
                'cbc_modules_alpdesk-core' => 1,
                'cbc_modules_layout' => 1,
                'cbc_modules_benutzer' => 1,
                'cbc_modules_system' => 1,
              ),
            ),
            '_contao_fe_attributes' => 
            array (
            ),
          ),
           'usageIndex' => 6,
           'usageReporter' => 
          Closure::__set_state(array(
          )),
        )),
        'contao_backend' => 
        Symfony\Component\HttpFoundation\Session\SessionBagProxy::__set_state(array(
           'bag' => 
          Contao\CoreBundle\Session\Attribute\ArrayAttributeBag::__set_state(array(
             'name' => 'contao_backend',
             'storageKey' => '_contao_be_attributes',
             'attributes' => 
            array (
              'fieldset_states' => 
              array (
                'tl_user' => 
                array (
                  'theme_legend' => 1,
                  'alpdeskcore_legend' => 1,
                ),
                'tl_settings' => 
                array (
                  'backend_legend' => 1,
                  'security_legend' => 1,
                  'files_legend' => 1,
                  'uploads_legend' => 1,
                ),
                'tl_member' => 
                array (
                  'homedir_legend' => 1,
                ),
                'tl_layout' => 
                array (
                  'jquery_legend' => 1,
                ),
                'tl_user_group' => 
                array (
                  'alexf_legend' => 1,
                  'alpdeskcore_legend' => 1,
                  'modules_legend' => 0,
                ),
              ),
              'new_records' => 
              array (
                'tl_theme' => 
                array (
                  0 => '1',
                ),
                'tl_layout' => 
                array (
                  0 => '1',
                ),
                'tl_alpdeskcore_sessions' => 
                array (
                  0 => '2',
                ),
                'tl_user_group' => 
                array (
                  0 => '1',
                ),
                'tl_user' => 
                array (
                  0 => '2',
                ),
                'tl_alpdeskcore_databasemanager' => 
                array (
                  0 => '2',
                ),
              ),
              'filetree' => 
              array (
                'c7c86130' => 1,
                '25eadaf9' => 1,
                'f45857ec' => 1,
                '5b5f7a49' => 1,
                'e7e45088' => 1,
              ),
              'tl_page_tree' => 
              array (
                1 => 1,
                2 => 0,
              ),
              'tl_article_tl_page_tree' => 
              array (
                1 => 0,
              ),
              'checkbox_groups' => 
              array (
                'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
                'cbc_modules_alpdesk-core' => 1,
                'cbc_modules_layout' => 1,
                'cbc_modules_benutzer' => 1,
                'cbc_modules_system' => 1,
              ),
            ),
          )),
           'data' => 
          array (
            '_sf2_attributes' => 
            array (
              '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
              'referer' => 
              array (
                'IcASpCXx' => 
                array (
                  'last' => '',
                  'current' => '/contao',
                ),
              ),
            ),
            '_symfony_flashes' => 
            array (
            ),
            '_contao_be_attributes' => 
            array (
              'fieldset_states' => 
              array (
                'tl_user' => 
                array (
                  'theme_legend' => 1,
                  'alpdeskcore_legend' => 1,
                ),
                'tl_settings' => 
                array (
                  'backend_legend' => 1,
                  'security_legend' => 1,
                  'files_legend' => 1,
                  'uploads_legend' => 1,
                ),
                'tl_member' => 
                array (
                  'homedir_legend' => 1,
                ),
                'tl_layout' => 
                array (
                  'jquery_legend' => 1,
                ),
                'tl_user_group' => 
                array (
                  'alexf_legend' => 1,
                  'alpdeskcore_legend' => 1,
                  'modules_legend' => 0,
                ),
              ),
              'new_records' => 
              array (
                'tl_theme' => 
                array (
                  0 => '1',
                ),
                'tl_layout' => 
                array (
                  0 => '1',
                ),
                'tl_alpdeskcore_sessions' => 
                array (
                  0 => '2',
                ),
                'tl_user_group' => 
                array (
                  0 => '1',
                ),
                'tl_user' => 
                array (
                  0 => '2',
                ),
                'tl_alpdeskcore_databasemanager' => 
                array (
                  0 => '2',
                ),
              ),
              'filetree' => 
              array (
                'c7c86130' => 1,
                '25eadaf9' => 1,
                'f45857ec' => 1,
                '5b5f7a49' => 1,
                'e7e45088' => 1,
              ),
              'tl_page_tree' => 
              array (
                1 => 1,
                2 => 0,
              ),
              'tl_article_tl_page_tree' => 
              array (
                1 => 0,
              ),
              'checkbox_groups' => 
              array (
                'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
                'cbc_modules_alpdesk-core' => 1,
                'cbc_modules_layout' => 1,
                'cbc_modules_benutzer' => 1,
                'cbc_modules_system' => 1,
              ),
            ),
            '_contao_fe_attributes' => 
            array (
            ),
          ),
           'usageIndex' => 6,
           'usageReporter' => 
          Closure::__set_state(array(
          )),
        )),
        'contao_frontend' => 
        Symfony\Component\HttpFoundation\Session\SessionBagProxy::__set_state(array(
           'bag' => 
          Contao\CoreBundle\Session\Attribute\ArrayAttributeBag::__set_state(array(
             'name' => 'contao_frontend',
             'storageKey' => '_contao_fe_attributes',
             'attributes' => 
            array (
            ),
          )),
           'data' => 
          array (
            '_sf2_attributes' => 
            array (
              '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
              'referer' => 
              array (
                'IcASpCXx' => 
                array (
                  'last' => '',
                  'current' => '/contao',
                ),
              ),
            ),
            '_symfony_flashes' => 
            array (
            ),
            '_contao_be_attributes' => 
            array (
              'fieldset_states' => 
              array (
                'tl_user' => 
                array (
                  'theme_legend' => 1,
                  'alpdeskcore_legend' => 1,
                ),
                'tl_settings' => 
                array (
                  'backend_legend' => 1,
                  'security_legend' => 1,
                  'files_legend' => 1,
                  'uploads_legend' => 1,
                ),
                'tl_member' => 
                array (
                  'homedir_legend' => 1,
                ),
                'tl_layout' => 
                array (
                  'jquery_legend' => 1,
                ),
                'tl_user_group' => 
                array (
                  'alexf_legend' => 1,
                  'alpdeskcore_legend' => 1,
                  'modules_legend' => 0,
                ),
              ),
              'new_records' => 
              array (
                'tl_theme' => 
                array (
                  0 => '1',
                ),
                'tl_layout' => 
                array (
                  0 => '1',
                ),
                'tl_alpdeskcore_sessions' => 
                array (
                  0 => '2',
                ),
                'tl_user_group' => 
                array (
                  0 => '1',
                ),
                'tl_user' => 
                array (
                  0 => '2',
                ),
                'tl_alpdeskcore_databasemanager' => 
                array (
                  0 => '2',
                ),
              ),
              'filetree' => 
              array (
                'c7c86130' => 1,
                '25eadaf9' => 1,
                'f45857ec' => 1,
                '5b5f7a49' => 1,
                'e7e45088' => 1,
              ),
              'tl_page_tree' => 
              array (
                1 => 1,
                2 => 0,
              ),
              'tl_article_tl_page_tree' => 
              array (
                1 => 0,
              ),
              'checkbox_groups' => 
              array (
                'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
                'cbc_modules_alpdesk-core' => 1,
                'cbc_modules_layout' => 1,
                'cbc_modules_benutzer' => 1,
                'cbc_modules_system' => 1,
              ),
            ),
            '_contao_fe_attributes' => 
            array (
            ),
          ),
           'usageIndex' => 6,
           'usageReporter' => 
          Closure::__set_state(array(
          )),
        )),
      ),
       'started' => false,
       'closed' => true,
       'saveHandler' => 
      Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy::__set_state(array(
         'wrapper' => false,
         'saveHandlerName' => 'files',
         'handler' => 
        Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler::__set_state(array(
           'sessionName' => 'PHPSESSID',
           'newSessionId' => NULL,
           'igbinaryEmptyData' => '',
           'handler' => 
          SessionHandler::__set_state(array(
          )),
        )),
      )),
       'metadataBag' => 
      Symfony\Component\HttpFoundation\Session\Storage\MetadataBag::__set_state(array(
         'name' => '__metadata',
         'storageKey' => '_sf2_meta',
         'meta' => 
        array (
          'u' => 1689580057,
          'c' => 1689579509,
          'l' => 0,
        ),
         'lastUsed' => 1689580057,
         'updateThreshold' => 0,
      )),
    )),
     'flashName' => 'flashes',
     'attributeName' => 'attributes',
     'data' => 
    array (
      '_sf2_attributes' => 
      array (
        '_security_contao_backend' => 'O:75:"Symfony\\Component\\Security\\Http\\Authenticator\\Token\\PostAuthenticationToken":2:{i:0;s:14:"contao_backend";i:1;a:5:{i:0;O:18:"Contao\\BackendUser":3:{s:5:"admin";b:1;s:3:"amg";a:0:{}s:6:"parent";a:6:{s:2:"id";i:1;s:8:"username";s:9:"xprojects";s:8:"password";s:60:"$2y$13$FvzBBD6v.UcruteOvIW4Uu5BMBi7e9Rryhe7/bU/nannAMsk4hPQm";s:7:"disable";b:0;s:5:"start";s:0:"";s:4:"stop";s:0:"";}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:4:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;s:22:"ROLE_ALLOWED_TO_SWITCH";i:3;s:29:"ROLE_ALLOWED_TO_SWITCH_MEMBER";}}}',
        'referer' => 
        array (
          'IcASpCXx' => 
          array (
            'last' => '',
            'current' => '/contao',
          ),
        ),
      ),
      '_symfony_flashes' => 
      array (
      ),
      '_contao_be_attributes' => 
      array (
        'fieldset_states' => 
        array (
          'tl_user' => 
          array (
            'theme_legend' => 1,
            'alpdeskcore_legend' => 1,
          ),
          'tl_settings' => 
          array (
            'backend_legend' => 1,
            'security_legend' => 1,
            'files_legend' => 1,
            'uploads_legend' => 1,
          ),
          'tl_member' => 
          array (
            'homedir_legend' => 1,
          ),
          'tl_layout' => 
          array (
            'jquery_legend' => 1,
          ),
          'tl_user_group' => 
          array (
            'alexf_legend' => 1,
            'alpdeskcore_legend' => 1,
            'modules_legend' => 0,
          ),
        ),
        'new_records' => 
        array (
          'tl_theme' => 
          array (
            0 => '1',
          ),
          'tl_layout' => 
          array (
            0 => '1',
          ),
          'tl_alpdeskcore_sessions' => 
          array (
            0 => '2',
          ),
          'tl_user_group' => 
          array (
            0 => '1',
          ),
          'tl_user' => 
          array (
            0 => '2',
          ),
          'tl_alpdeskcore_databasemanager' => 
          array (
            0 => '2',
          ),
        ),
        'filetree' => 
        array (
          'c7c86130' => 1,
          '25eadaf9' => 1,
          'f45857ec' => 1,
          '5b5f7a49' => 1,
          'e7e45088' => 1,
        ),
        'tl_page_tree' => 
        array (
          1 => 1,
          2 => 0,
        ),
        'tl_article_tl_page_tree' => 
        array (
          1 => 0,
        ),
        'checkbox_groups' => 
        array (
          'cbc_alexf_tl_alpdeskcore_databasemanager' => 0,
          'cbc_modules_alpdesk-core' => 1,
          'cbc_modules_layout' => 1,
          'cbc_modules_benutzer' => 1,
          'cbc_modules_system' => 1,
        ),
      ),
      '_contao_fe_attributes' => 
      array (
      ),
    ),
     'usageIndex' => 6,
     'usageReporter' => 
    Closure::__set_state(array(
    )),
  )),
   'locale' => NULL,
   'defaultLocale' => 'en',
   'preferredFormat' => NULL,
   'isHostValid' => true,
   'isForwardedValid' => true,
))

@xprojects-de
Copy link
Contributor Author

It has to be said that the behavior only occurs if you are logged into the backend at the same time and, for example, use the API via a JS application in the same browser.

@Toflar
Copy link
Member

Toflar commented Jul 17, 2023

Ah I see, it's the TokenChecker that actually fails. @aschempp should that one check the _scope as well instead of just checking all firewalls?

@leofeyer leofeyer added this to the 5.1 milestone Jul 17, 2023
@aschempp
Copy link
Member

Not sure what you mean @Toflar. The TokenChecker is supposed to read the session. However, it also does a hasSession check, and shouldn't do anything if there is no session.

I'm not really sure we currently support a stateless firewall concept. I'm also not sure it would actually be needed for that use case, because if a user is logged in to the back end, a session cookie would already be present and the regular firewall should work as usual, as long as the API endpoint has _scope=backend?

@fritzmg
Copy link
Contributor

fritzmg commented Jul 24, 2023

However, it also does a hasSession check, and shouldn't do anything if there is no session.

The hasSession check returns true if there was a previous session - which will be the case since there will be a session cookie from the back end login.

@leofeyer leofeyer added the up for discussion Issues and PRs which will be discussed in our monthly Mumble calls. label Jul 28, 2023
@xprojects-de
Copy link
Contributor Author

xprojects-de commented Aug 4, 2023

The hasSession check returns true if there was a previous session - which will be the case since there will be a session cookie from the back end login.

Exactly. that is the case here and I think if a request comes with a different scope then backend (here "alpdeskapi"), no session should be started anyway.

I agree with @Toflar that the scope should also be checked.

@aschempp
Copy link
Member

If there is a session from the back end login, then there is a session – and none would be newly started?

@aschempp
Copy link
Member

Reading the initial topic again… I think it is incorrect to use a stateless firewall for this case then, since you MUST access the session to check the back end user. A stateless firewall only makes sense for a non-browser-API (because of no session cookies) imho.

@fritzmg
Copy link
Contributor

fritzmg commented Aug 11, 2023

I think it is incorrect to use a stateless firewall for this case then, since you MUST access the session to check the back end user.

But they are not checking the back end user.

@xprojects-de
Copy link
Contributor Author

A stateless firewall only makes sense for a non-browser-API (because of no session cookies) imho.

This is exactly the use case here, but the API is also served by a JS JPA. I think that should be allowed too!
In principle, this also works and Symfony does the right thing, but Contao doesn't!
Due to the separate scope and the separate firewall, Contao should not start a session even if a session cookie is set!
In my opinion, this should only be the case if the "backend" scope is active!

Due to the separate scope of request, it does not go to the Contao backend and does not check the backend user either.

@fritzmg
Copy link
Contributor

fritzmg commented Aug 11, 2023

@aschempp here is a minimal reproduction for the contao/managed-edition:

// src/ContaoManager/Plugin.php
namespace App\ContaoManager;

use Contao\ManagerPlugin\Config\ContainerBuilder;
use Contao\ManagerPlugin\Config\ExtensionPluginInterface;
use Symfony\Component\Security\Core\User\InMemoryUser;

class Plugin implements ExtensionPluginInterface
{
    public function getExtensionConfig($extensionName, array $extensionConfigs, ContainerBuilder $container)
    {
        if ('security' !== $extensionName) {
            return $extensionConfigs;
        }

        foreach ($extensionConfigs as &$extensionConfig) {
            if (!isset($extensionConfig['firewalls'])) {
                continue;
            }

            $extensionConfig['providers']['foobar_user_provider'] = [
                'memory' => [
                    'users' => [
                        'foobar' => ['password' => '$2y$13$WIRT.J5YD5Qor5l4QhTSoulA9J.a7Gek1oXBp2htkxg440ABmayay', 'roles' => 'ROLE_USER'],
                    ],
                ],
            ];

            $extensionConfig['firewalls'] = [
                'foobar' => [
                    'pattern' => '^/foobar',
                    'http_basic' => ['realm' => 'Foobar'],
                    'provider' => 'foobar_user_provider',
                    'stateless' => true,
                ]
            ] + $extensionConfig['firewalls'];

            $extensionConfig['access_control'] = [['path' => '^/foobar', 'roles' => 'ROLE_USER']] + $extensionConfig['access_control'];
            $extensionConfig['password_hashers'][InMemoryUser::class] = 'auto';

            break;
        }

        return $extensionConfigs;
    }
}
// src/Controller/FoobarController.php
namespace App\Controller;

use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

#[Route('/foobar')]
class FoobarController
{
    public function __invoke(): Response
    {
        return new Response('Hello World!');
    }
}
  1. composer install
  2. Log into the back end or front end.
  3. Access the /foobar route.
  4. The following error will occur: Session was used while the request was declared stateless..

Note that this is a completely separate firewall for a completely separate controller, independent from Contao itself. But the error described in this issue will still occur, if you first log into the Contao front or back end and then access the /foobar route.

@aschempp
Copy link
Member

aschempp commented Aug 16, 2023

I understand why the problem happens. Your browser has a session cookie from the back end login, that's why hasPreviousSession returns true. The fact that you do have a session cookie, means using a stateless firewall would not be necessary!

@xprojects-de if I understand correctly, your SPA is a tool for front end editing of Contao content? How do I authenticate in that application (how do you get the stateless firewall token)?

@xprojects-de
Copy link
Contributor Author

@aschempp thanks for the reply.

I understand why the problem happens. Your browser has a session cookie from the back end login, that's why hasPreviousSession returns true.

That's true, but it has nothing to do with frontend editing.

My use case is as follows:

  1. Own Api (booking system for rooms) with own JS SPA (Angular based)
  2. The API is served via its own firewall and its own controller
  3. The authentication is independent of the Contao backend user
  4. Contao is independent of this and is not required for the API

The authentication runs via its own Authguard with its own administration in the database. The Contao backend user is not used.

@fritzmg
Copy link
Contributor

fritzmg commented Aug 16, 2023

The fact that you do have a session cookie, means using a stateless firewall would not be necessary!

But the session was created for an entirely different firewall.

@aschempp
Copy link
Member

I see, sorry @xprojects-de I was confused with another GitHub issue then 😅

But the session was created for an entirely different firewall.

Obviously, but that does not really matter. There's a session cookie, so there's a previous session 😂

So maybe we need to check for the _stateless attribute in addition to hasPreviousSession?

@fritzmg
Copy link
Contributor

fritzmg commented Aug 16, 2023

There's a session cookie, so there's a previous session 😂

But from a different firewall. The point is that the TokenChecker should not start a new session for the current firewall.

So maybe we need to check for the _stateless attribute in addition to hasPreviousSession?

Seems reasonable. Or should the TokenChecker just check for the Contao _scopes instead (frontend and backend)?

@leofeyer leofeyer modified the milestones: 5.1, 5.2 Aug 16, 2023
@bytehead
Copy link
Member

Maybe related to this: symfony/symfony#51319

@leofeyer
Copy link
Member

leofeyer commented Aug 24, 2023

Related discussions: symfony/symfony#50715, symfony/symfony#48044 (comment)

@aschempp
Copy link
Member

aschempp commented Aug 24, 2023

There is already an issue in Symfony about this: symfony/symfony#50715

@xprojects-de you can bypass this in your own routes by setting the route flag symfony/symfony#48044 (comment) or downgrade to Symfony 6.2 in the meantime.

@leofeyer leofeyer removed the up for discussion Issues and PRs which will be discussed in our monthly Mumble calls. label Aug 24, 2023
@fritzmg
Copy link
Contributor

fritzmg commented Aug 24, 2023

For reference, here is the stack trace again:

Symfony\Component\HttpKernel\Exception\UnexpectedSessionUsageException:
Session was used while the request was declared stateless.

  at vendor\symfony\http-kernel\EventListener\AbstractSessionListener.php:213
  at Symfony\Component\HttpKernel\EventListener\AbstractSessionListener->onKernelResponse(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
     (vendor\symfony\event-dispatcher\Debug\WrappedListener.php:116)
  at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
     (vendor\symfony\event-dispatcher\EventDispatcher.php:220)
  at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.response', object(ResponseEvent))
     (vendor\symfony\event-dispatcher\EventDispatcher.php:56)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
     (vendor\symfony\event-dispatcher\Debug\TraceableEventDispatcher.php:139)
  at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
     (vendor\symfony\http-kernel\HttpKernel.php:199)
  at Symfony\Component\HttpKernel\HttpKernel->filterResponse(object(Response), object(Request), 1)
     (vendor\symfony\http-kernel\HttpKernel.php:187)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor\symfony\http-kernel\HttpKernel.php:74)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor\symfony\http-kernel\Kernel.php:197)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public\index.php:44)

And the session is started via our TokenChecker via our PreviewToolbarListener:

  at vendor\contao\contao\core-bundle\src\Security\Authentication\Token\TokenChecker.php:217
  at Contao\CoreBundle\Security\Authentication\Token\TokenChecker->getTokenFromSession('_security_contao_backend')
     (vendor\contao\contao\core-bundle\src\Security\Authentication\Token\TokenChecker.php:166)
  at Contao\CoreBundle\Security\Authentication\Token\TokenChecker->getToken('contao_backend')
     (vendor\contao\contao\core-bundle\src\Security\Authentication\Token\TokenChecker.php:66)
  at Contao\CoreBundle\Security\Authentication\Token\TokenChecker->hasBackendUser()
     (vendor\contao\contao\core-bundle\src\EventListener\PreviewToolbarListener.php:47)
  at Contao\CoreBundle\EventListener\PreviewToolbarListener->__invoke(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
     (vendor\symfony\event-dispatcher\Debug\WrappedListener.php:116)
  at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
     (vendor\symfony\event-dispatcher\EventDispatcher.php:220)
  at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.response', object(ResponseEvent))
     (vendor\symfony\event-dispatcher\EventDispatcher.php:56)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
     (vendor\symfony\event-dispatcher\Debug\TraceableEventDispatcher.php:139)
  at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
     (vendor\symfony\http-kernel\HttpKernel.php:199)
  at Symfony\Component\HttpKernel\HttpKernel->filterResponse(object(Response), object(Request), 1)
     (vendor\symfony\http-kernel\HttpKernel.php:187)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor\symfony\http-kernel\HttpKernel.php:74)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor\symfony\http-kernel\Kernel.php:197)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public\index.php:44) 

@leofeyer leofeyer linked a pull request Aug 24, 2023 that will close this issue
leofeyer pushed a commit that referenced this issue Aug 24, 2023
Description
-----------

Fixes #6220

Commits
-------

f11760d Check preview script before firewall
leofeyer pushed a commit to contao/core-bundle that referenced this issue Aug 24, 2023
Description
-----------

Fixes contao/contao#6220

Commits
-------

f11760d3 Check preview script before firewall
leofeyer pushed a commit that referenced this issue Aug 24, 2023
Description
-----------

In Symfony 5.3 this config was added to the default security config in order to enable the `auto` password hasher for all user classes that implement this interface (see symfony/recipes#981) - which `Contao\User` also implements.

I think we should do the same in the `contao/managed-edition`. This way you don't have to define this yourself in case you are using HTTP Basic Authentication for some controller outside Contao's own firewalls. For instance, in [this example](#6220 (comment)) the line

```php
$extensionConfig['password_hashers'][InMemoryUser::class] = 'auto';
```

could be omitted then.

Commits
-------

84c6d47 set auto password hasher to auto for all
ab0a671 also set password hasher for Contao\User specifically
593d244 update README and test config
leofeyer pushed a commit to contao/core-bundle that referenced this issue Aug 24, 2023
Description
-----------

In Symfony 5.3 this config was added to the default security config in order to enable the `auto` password hasher for all user classes that implement this interface (see symfony/recipes#981) - which `Contao\User` also implements.

I think we should do the same in the `contao/managed-edition`. This way you don't have to define this yourself in case you are using HTTP Basic Authentication for some controller outside Contao's own firewalls. For instance, in [this example](contao/contao#6220 (comment)) the line

```php
$extensionConfig['password_hashers'][InMemoryUser::class] = 'auto';
```

could be omitted then.

Commits
-------

84c6d47a set auto password hasher to auto for all
ab0a6719 also set password hasher for Contao\User specifically
593d2448 update README and test config
leofeyer pushed a commit to contao/manager-bundle that referenced this issue Aug 24, 2023
Description
-----------

In Symfony 5.3 this config was added to the default security config in order to enable the `auto` password hasher for all user classes that implement this interface (see symfony/recipes#981) - which `Contao\User` also implements.

I think we should do the same in the `contao/managed-edition`. This way you don't have to define this yourself in case you are using HTTP Basic Authentication for some controller outside Contao's own firewalls. For instance, in [this example](contao/contao#6220 (comment)) the line

```php
$extensionConfig['password_hashers'][InMemoryUser::class] = 'auto';
```

could be omitted then.

Commits
-------

84c6d47a set auto password hasher to auto for all
ab0a6719 also set password hasher for Contao\User specifically
593d2448 update README and test config
@xprojects-de
Copy link
Contributor Author

Thanks to all!
Works fine with 4.13 and 5.2!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants