-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Fix context listener misbehaviour #20401
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
[Security] Fix context listener misbehaviour #20401
Conversation
👍 |
@@ -166,13 +166,13 @@ protected function refreshUser(TokenInterface $token) | |||
|
|||
return $token; | |||
} catch (UnsupportedUserException $e) { | |||
// let's try the next user provider | |||
continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why drop the comment (which is accurate) and add a continue (which is useless) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Nek- I could also let it as it. But continue
seems more appropriate to me (for now we just want to continue the loop and not go further). But just a matter of taste.
Imo the context listener should rather not try to use all user providers to refresh the user, but should only use the user provider that was configured for the active firewall. |
@xabbuh Agreed. But the question still remain when there is no provider configured for the firewall, doesn't it? |
@Einenlum It should then use the first configured user provider like it's done elsewhere. |
This is very optimistic solution :P If you have 3 providers and you need the 3th, then the first two will query, fetch or something their backends on every page load. For example 3 query per page load just to refresh the user... and can be worse if you have rest api providers or anything else slow. And the continue doesn't do anything there, if you just use that exception (UnsupportedException) then you are doing the same thing :) Checking the firewall's provider is tricky too, because:
So you don't really know, which method (provider) the user came from. The only solution would be to save the provider in the token or user, but as fabpot said in the connected issue, it was there once, and they removed it for unkown reasons. Changing the tokeninterface would be big bc break, so no much hope :P |
Note that BC breaks are not allowed, so you'll need another approach if you need this in the core. |
closing in favour of #21791 |
This PR was merged into the 2.7 branch. Discussion ---------- [SecurityBundle] only pass relevant user provider | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #4498, #12465, #20401, #21737 | License | MIT | Doc PR | There is no need for the context listener to be aware of all the configured user providers. It must only use the provider for the current firewall (the one identified by the context key passed to the constructor) to refresh the user from the session. Commits ------- d97e07f [SecurityBundle] only pass relevant user provider
The implementation of
ContextListener
is not logical.Here is the actual difference between the
ContextListener
and theChainUserProvider
.The
ContextListener
will only loop if the provider throws anUnsupportedUserException
:The
ChainUserProvider
on the other hand, will try to refresh the user with every provider even if the user was not found :This is not only undocumented, it is also very disturbing. This leads to strange behaviours: If you had not set a chain provider, the login is successful but right after the redirection you're anonymous again without form error.
We really need to fix this incoherent behaviour.
ChainProvider
should be necessary only if you want to use multiple providers for a specific firewall.