-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[Cookbook][Security] How to Create a Custom Form Password Authenticator #4579
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
Comments
@burci Can you elaborate a bit more why the current code leads to an infinite loops. Honestly, I don't see the issue yet. |
Hmm, I'm afraid I don't understand the issue either. Can you please explain a bit more? |
Maybe i was not clear enough, sorry. Let's go step by step: 1, The example at https://github.com/symfony/symfony-docs/blob/master/cookbook/security/custom_password_authenticator.rst was not working for me. 2, The problem was that 3, The 4, The 5, So in the next request it is going to be empty. 6, I suggest instead of using the |
Ah, I think I get what you mean (and what's wrong with the example code). Thanks for debugging & the detailed description! So if I understand you correctly, you propose this change? - $passwordValid = $this->encoder->isPasswordValid($user, $token->getCredentials());
+ $currentUser = $token->getUser();
+
+ if ($currentUser instanceof UserInterface) {
+ if ($currentUser->getPassword() !== $user->getPassword()) {
+ throw new BadCredentialsException('The credentials were changed from another session.');
+ }
+ } else {
+ if ('' === ($presentedPassword = $token->getCredentials())) {
+ throw new BadCredentialsException('The presented password cannot be empty.');
+ }
+ if (!$this->encoderFactory->getEncoder($user)->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) {
+ throw new BadCredentialsException('The presented password is invalid.');
+ }
+ } |
@burci |
@wouterj yes, something like this. In my code I use DaoAuthenticationProvider in order not to reimplement this logic, but maybe using it is not clear enought for this example... @stof The user object is not touched by the eraseCredentials, only the token. In the current https://github.com/symfony/symfony-docs/blob/master/cookbook/security/custom_password_authenticator.rst password is checked with: This means that the code tries to check the user password always against $token->getCredentials() which is going to be null because AuthenticationProviderManager will erase it right after the first successful authentication. In the documentation there is a part mentioning "Ultimately, your job is to return a new token object" which would make only sense if AuthenticationProviderManager would not eraseCredentials on the result token, but on the original one: https://github.com/symfony/Security/blob/master/Core/Authentication/AuthenticationProviderManager.php#L96 |
@burci |
@stof when i wrote "user object is not touched" i mean it does not change it, in my implementation the function is empty:
Sorry if I was not clear enough. This is a real documentation error, and it is not related to my local implementation. As @wouterj already pointed out, the problem is that eraseCredentials is going to set the token's credential to null https://github.com/symfony/Security/blob/master/Core/Authentication/Token/UsernamePasswordToken.php#L88 so the
is only enough to check the token at login time, in the next request $passwordValid is going to be false. This is why DaoAuthenticationProvider also checks against the $token->getUser(), i think this lines describes the situation clearly: |
I just encountered exactly the same thing by implementing the recipe from http://symfony.com/doc/2.4/cookbook/security/custom_authentication_provider.html. The authenticate metod is being called twice, and the second time the token's credentials indeed are null and hence an infinite loop. The scenario I encountered is detailed step by step on this question of over 1 year old: So this seems like a documentation error for me two. |
…ple (javiereguiluz) This PR was merged into the 2.8 branch. Discussion ---------- Fixed the code of the custom password authenticator example Fixes #4579. I used the same code given by @wouterj in #4579 (comment) Commits ------- ad726c1 Fixed the code of the custom password authenticator example
Fixed by #10100. |
In the page https://github.com/symfony/symfony-docs/blob/master/cookbook/security/custom_password_authenticator.rst the next code leads to endless loop:
because after the validation was successfull credentials being cleard, so the $token->getCredentials() will be null.
It would be better to use same logic then in https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php#L54 (or the whole DaoAuthenticationProvider)
I can make a pull request if this direction is correct.
(Maybe DaoAuthenticationProvider should renamed to UserProviderBasedAuthenticationProvider or something similar)
The text was updated successfully, but these errors were encountered: