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

Possible break in symfony 4.4.1 / auth is dismissed #34875

Closed
psohm opened this issue Dec 8, 2019 · 16 comments
Closed

Possible break in symfony 4.4.1 / auth is dismissed #34875

psohm opened this issue Dec 8, 2019 · 16 comments

Comments

@psohm
Copy link

psohm commented Dec 8, 2019

Symfony version(s) affected: 4.4.1

Description
Authentication information is dismissed on every page. User have to re auth every page.
I personnaly think that the status "fully authenticated" of the user isn't registered.

How to reproduce
Have a auth process which works in 4.3 (or 4.4.0)
update to "symfony/security-bundle": "4.4.1"

Possible Solution
In composer.json revert to "symfony/security-bundle": "4.4.0"

Additional context
[2019-12-08 11:36:37] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\Component\Security\Core\Exception\AccessDeniedException(code: 403): Access Denied. at C:\Travail\Emporium\EmporiumWeb\vendor\symfony\security-http\Firewall\AccessListener.php:99)"} []
[2019-12-08 11:36:37] security.DEBUG: Calling Authentication entry point. [] []
[2019-12-08 11:36:37] request.INFO: Matched route "security_login". {"route":"security_login","route_parameters":{"_route":"security_login","_controller":"App\Controller\SecurityController::login"},"request_uri":"http://127.0.0.1:8000/login","method":"GET"} []
[2019-12-08 11:36:37] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2019-12-08 11:36:37] request.INFO: Matched route "_wdt". {"route":"_wdt","route_parameters":{"_route":"_wdt","_controller":"web_profiler.controller.profiler::toolbarAction","token":"da16a8"},"request_uri":"http://127.0.0.1:8000/_wdt/da16a8","method":"GET"} []

@xabbuh
Copy link
Member

xabbuh commented Dec 8, 2019

Can you create a small example application that allows to reproduce your issue?

@mrohnstock
Copy link
Contributor

Just my two cents: I'm in the same boat, but with the upgrade from symfony 4.3.8 to 4.3.9.
With symfony/security-bundle v4.3.9 I'll get logged out after each request, with v4.3.8 everything is ok.

Can't provide a small example application, as I'm using doctrine-odm for the user provider :(...

@chalasr
Copy link
Member

chalasr commented Dec 16, 2019

We definitely need a reproducer. It’s fine if it requires mongodb, although replacing the provider should be pretty easy and should not make any difference regarding the reported issue.

@xabbuh
Copy link
Member

xabbuh commented Dec 23, 2019

I am going to close here for now due to the lack of feedback. Please let us know when you have more information and we can consider to reopen.

@xabbuh xabbuh closed this as completed Dec 23, 2019
@meiyo-hu
Copy link

meiyo-hu commented Jan 6, 2020

I am also having the same (or a similar) issue.

When using multiple Guard Authenticators that all support the same request but none of them returns a response object on success, all authenticators get executed, even when the first one already authenticated the user and set the token. Before 4.4.1 one could return null in the onAuthenticationSuccess() and use the supports() method to check the state of the authentication and skip all guards after the user was successfully authenticated. Since 4.4.1 the supports() methods get called eagerly thus cannot be used to skip a guard based on the success of a previous guard. The only way to skip later guards is to set a Response object but that is not a solution in my case.

The particular commit that introduced the changes: b20ebe6

Modifying the GuardAuthenticationListener::executeGuardAuthenticator() method to return the token and then breaking out of the caller loop if the $token->isAuthenticated() returns true solves the login issues for me. But I don't know if this would be the right solution. Maybe I misunderstood the usage of the Guard Authenticator class and should refactor my authentication logic. In this case, I think maybe the related sections in the Symfony docs could be updated to clarify that all supports() methods of all guards will be executed eagerly and thus cannot be used to skip guards based on the authentication state.

@nicolas-grekas
Copy link
Member

Symfony docs could be updated to clarify that all supports() methods of all guards will be executed eagerly and thus cannot be used to skip guards based on the authentication state.

I think that'd be the solution yes. Can you please consider sending a doc PR?
This description is correct.

@meiyo-hu
Copy link

meiyo-hu commented Jan 8, 2020

Yes, I could send a doc PR.

But even if I misunderstood something about Guard Authenticators, the fact is that they worked significantly differently before 4.4.1. We built our authentication system on the old way of functioning and it has worked as intended for more than a year, until the 4.4.1 patch broke it.

So if I want to be correct, I would also mention in the updated doc that the behavior has changed since 4.4.1 because of the BC breaking side effect of a fix.

This sounds like a last resort for me, only for the case when there's no way to fix the issue without breaking something other, possibly more important parts.

@psohm
Copy link
Author

psohm commented Jan 8, 2020

I don't understand your fix @meiyo-hu do you have any example ?

@meiyo-hu
Copy link

meiyo-hu commented Jan 9, 2020

I don't have a solution for the problem, sorry if I wrongly implied that. The example modification I was mentioning earlier that fixed the issue in my specific case was just a quick tampering with the guard execution logic to test that the root of the issue comes from the altered execution flow. But I see that it only solves my problem as a side effect but could cause backward compatibility issues in other cases.

Here is a repo with a very dump and simple example code, that reproduces the problem: https://github.com/meiyo-hu/symfony-issue34875

Maybe this kind of usage pattern is arguable, but I don't think it relies on a buggy behavior and it was possible in 4.4.0 and now it fails since 4.4.1.

@chalasr
Copy link
Member

chalasr commented Jan 9, 2020

Thank you for the reproducer @meiyo-hu. Reopening to keep track of this issue, which will likely be resolved via documentation only (in our CHANGELOG/UPGRADE files and/or on https://github.com/symfony/symfony-docs).

@diegoOgueta
Copy link

Hi, i am also having the similar problem using multiple authentication guards.

We are migrating from version 4.3 to 4.4 and I am using this documentation: https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.4.md

I cound't see any related changes about multiple authentication guards. In my case, i have one route setup with 3 authenticators and a chain provider. Example:

in_memory_example:
            memory:
                users:
                   {.... some users}

model_provider_example:
            id: App\Security\User\UserProvider

 chain_provider:
            chain:
                providers: [in_memory_example, model_provider_example]

firewalls:
        graphql:
            pattern: ^/public
            stateless: true
            anonymous: true
            guard:
                authenticators:
                    - 'App\Security\CustomAuthenticator'
                    - 'App\Security\Custom2Authenticator'
                    - 'App\Security\Custom3Authenticator'
                entry_point: 'App\Security\Custom2Authenticator'
            provider: chain_provider

With symfony 4.3 i dont have any problem, but with symfony 4.4 if one supported authenticator success the process continues and did not stop. In this case Custom3Authenticator is supported too and fails with all the request.

If this is not a bug and the behavior for the multiple authentication guards has been changed for this version and the nexts. Where i can find the documentation to setup properly multiple authentication guards with this new changes?

Thanks.

@psohm
Copy link
Author

psohm commented Feb 18, 2020

Please try to revert composer.json to "symfony/security-bundle": "4.4.0" to see if it is the same issue.

@diegoOgueta
Copy link

Hi,

reverting the "symfony/security-bundle" to 4.4.0 did not work for me, but now, I fixed my problem using xdebug to debug symfony framework.

With this, I understood the new changes on "symfony/security-bundle" and I adapted my code to work with it. In my case the problem was on the support method of the authentication guards.
I reworked them to be more restricted and now is all gone fine.

Regards

@psohm
Copy link
Author

psohm commented Feb 19, 2020

in my case, the problem was solved (with 4.4 & 5.0) when I put stateless to true.

@chalasr
Copy link
Member

chalasr commented Feb 20, 2020

Can someone send a PR to the docs?
I'm going to close this issue for now. Thank you

@chalasr chalasr closed this as completed Feb 20, 2020
@psohm
Copy link
Author

psohm commented Apr 8, 2020

I found a working stateless = false solution
In the serialize / unserialize method I didn't put the email, I put therefore the id which was the PK
when I add the email in both methods, it was working
I don't know how the 4.4.0 auth was working but I bet it was relying on the primary key
maybe we should specify it in the documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants