Skip to content

[Security] Weird behavior of session&security (user not loaded), depending on a combination of 3(!) settings #60115

Closed as not planned
@ThomasLandauer

Description

@ThomasLandauer

Symfony version(s) affected

7.2.5

Description

I'm observing a difference between DEV and TEST environment. Took me days to nail this down! ;-)

  • config/packages/security.php contains:

    $security->provider('user_entity_provider')->entity()->class(User::class)->property('email');

    And a custom authenticator fetches the user via another entity:

    $userBadge = new UserBadge($token, function(string $token): ?User {
        return $this->logintokenRepository->findUserFromLogintoken($token);
    });

    The repository method ends like so:

    $logintoken = $queryBuilder->getQuery()->getOneOrNullResult();
    if ($logintoken instanceof Logintoken) {
        return $logintoken->getUser();
    }
  • config/packages/monolog.php contains:

    if ('dev' === $containerConfigurator->env()) {
        $monologConfig->handler('main')
          ->type('stream')
          ->path(param('kernel.logs_dir') . '/' . param('kernel.environment') . '.log')
        ;
    }
  • And in User.php the role is hard-coded like this:

    public function getRoles(): array
    {
        return ['ROLE_USER'];
    }

Then the following happens:

When opening the "login" URL in TEST environment, then the user is null (in the redirected controller) and the session file (in /var/lib/php/sessions/) looks like this:

_sf2_attributes|a:1:{s:14:"_security_main";s:283:"O:75:"Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken":2:{i:0;s:4:"main";i:1;a:5:{i:0;O:30:"Proxies\__CG__\App\Entity\User":2:{s:19:"App\Entity\Userid";i:1;s:30:"App\Entity\UserplainPassword";N;}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:1:{i:0;s:9:"ROLE_USER";}}}";}_sf2_meta|a:3:{s:1:"u";i:1743526505;s:1:"c";i:1743526505;s:1:"l";i:0;}_symfony_flashes|a:0:{}

When opening the same URL again in TEST environment, the user is present, and the session file changes to:

_sf2_attributes|a:1:{s:14:"_security_main";s:412:"O:75:"Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken":2:{i:0;s:4:"main";i:1;a:5:{i:0;O:15:"App\Entity\User":5:{s:19:"App\Entity\Userid";i:1;s:22:"App\Entity\Useremail";s:15:"foo@example.com";s:22:"App\Entity\Userroles";a:1:{i:0;s:9:"ROLE_USER";}s:25:"App\Entity\Userpassword";N;s:30:"App\Entity\UserplainPassword";N;}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:1:{i:0;s:9:"ROLE_USER";}}}";}_sf2_meta|a:3:{s:1:"u";i:1743526615;s:1:"c";i:1743526615;s:1:"l";i:0;}_symfony_flashes|a:0:{}

When opening the URL in DEV environment, the user is present, and the session file looks like this:

_sf2_attributes|a:1:{s:14:"_security_main";s:427:"O:75:"Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken":2:{i:0;s:4:"main";i:1;a:5:{i:0;O:30:"Proxies\__CG__\App\Entity\User":5:{s:19:"App\Entity\Userid";i:1;s:22:"App\Entity\Useremail";s:15:"foo@example.com";s:22:"App\Entity\Userroles";a:1:{i:0;s:9:"ROLE_USER";}s:25:"App\Entity\Userpassword";N;s:30:"App\Entity\UserplainPassword";N;}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:1:{i:0;s:9:"ROLE_USER";}}}";}_sf2_meta|a:3:{s:1:"u";i:1743526705;s:1:"c";i:1743526705;s:1:"l";i:0;}_symfony_flashes|a:0:{}

If I change any one of the three settings above, then DEV and TEST behave the same.

I'm guessing that in TEST, the user isn't fully loaded from the database, since the role can be figured out without it. But in DEV, Monolog wants to know exactly what's going on, so it forces a database lookup.

How to reproduce

Here's a reproducer: https://github.com/ThomasLandauer/symfony-issue-60115

My nginx config for TEST:

server {
    listen 80;

    server_name test.symfony-test-env-issue.localhost;
    root .../symfony-test-env-issue/public;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;

    location / {
        try_files $uri /index.php$is_args$args;
    }
    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT   $realpath_root;
        fastcgi_param APP_ENV         test;
        internal;
    }
    location ~ \.php$ {
        return 404;
    }
}

For DEV it's the same (URL: symfony-test-env-issue.localhost), just without this line:

fastcgi_param APP_ENV         test;

The "login" URL's are:

This gets redirected to /profile which does just dd($this->getUser());

Possible Solution

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions