Skip to content
Advertisement

Can’t login with Symfony Guard, maybe because of cookies & multidomain

I need a very simple form login, so I’m using a Symfony Guard authenticator for this.

My application is multi-domain, for now login is possible on only 3 of them (and 2 are subdomains). But I can’t log in on any of them.

First, here are some resources:

I don’t understand why, but to debug this, I tried updating config/packages/dev/web_profiler.yaml to set intercept_redirects: true, to debug cookies and security config, and here’s what I have when reproducing the common login scenario:

  • When accessing the backend page (that shows the login form) I have the session cookie with a value like llno5smlmsema5nq02kr30s6m2.
  • After I submit the form with correct values, I see the profiler’s redirection page, and the Web Debug Toolbar shows me that I’m Logged in as Pierstoval and the session cookie sent by the response changes id and becomes b1vbcnvp7e6p0j0o0vtd7ui7bf (because by default the Firewall migrates the session when logging in), so this works. I can even see that the token is in the session. I also added dump() statements in the Session::save() method, and dumping session content shows the token. And the token is in the session file when I dump it too (in var/sessions/dev/sess_b1vbcnvp7e6p0j0o0vtd7ui7bf).
  • I click on the http://back.esteren.docker/fr/ link showed by the redirection page, and then I see the session cookie id did not change (it’s the one that have been set after logging in), but this time, the Web Debug Toolbar shows me that I’m Logged in as anon..

To me, there’s a problem when the session is saved, so I took a look at the session files in var/sessions/dev/, after the redirection.

When I cat var/sessions/dev/sess_b1vbcnvp7e6p0j0o0vtd7ui7bf, I see this:

_sf2_attributes|a:2:{s:18:"_csrf/authenticate";s:43:"bCm23vBGyrq52caehAH9cCTjJkAmdT9j9Z8yygaET78";s:26:"_security.main.target_path";s:30:"http://back.esteren.docker/fr/";}_sf2_meta|a:3:{s:1:"u";i:1538092899;s:1:"c";i:1538092750;s:1:"l";s:5:"86400";}

Which, when unserializing the session attribute bag array, gives this:

array:2 [
  "_csrf/authenticate" => "bCm23vBGyrq52caehAH9cCTjJkAmdT9j9Z8yygaET78"
  "_security.main.target_path" => "http://back.esteren.docker/fr/"
]

This means the token has not been saved in the session after the successful login.

And even worse: since I already debugged the session file before redirecting, I know that it was saved ni the session and at some time it was removed from it before the session being saved another time.

How is this even possible? Did I forget something in my security configuration?

As a side-note, I tested with and without docker (with a plain php-fpm+nginx setup) and none worked, this probably means that it’s not a permission issue from the docker side…

Advertisement

Answer

Finally, thanks to @Lynn and @Wirone on the public Symfony Slack channels, I ended up with a solution.

First, the bug was the fact that my User entity (which is serialized in the session) did not store the password.
And when a token is created, it checks if the “old” (in session) user password is the same as the “new” (refreshed) one, thanks to the Abstractoken::hasUserChanged() method.

And if the user object has changed, the firewall logs the user out.

To fix this, either serialize the password with the user, or implement EquatableInterface and use your own checks.

And this is what I did:

  • Implement EquatableInterface
  • Serialize only id and the timestampable fields createdAt and updatedAt
  • Make isEqualTo() check class and date fields to know if the user has changed.

Hope this helps 👍

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement