-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
KernelBrowser reinitializes TokenStorage on subesequent Request calls #43266
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
I think you have this problem because of the changes from @nicolas-grekas:
I had also same problem, i was using tbh i'm not sure if his changes is correct, i think we should check if there is already a session before creating a new one right? So it should be:
Commit link: I hope this might help you. |
So this issue predates these changes by @nicolas-grekas, as 5.3.7 predates his commit. Also once I did update I'm afraid your fix doesn't work. I think it's because I'm only calling Even if implement your changes to framework.yaml and make this change
It still returns 403. |
@Philostastically if you are using a stateless authentication method (which is generally the case for APIs), being authenticated for a request does not make you being authenticated for the next one. You have to send the authentication headers in each request. |
@stof Ah, that makes sense. This is my firewall settings for my test env (for the relevant route).
Before I migrated to this version symfony (we were on 5.2), we had a custom Authenticator which had been deprecated because of some security flaws, but we kept it around for the tests because thsoe security flaws made it very easy to write manually in the context of tests. I'd rather not reimplement that authenticator, because it doesn't really represent the state of the server any more. Do you have a reccommendation for what can be done, if loginUser() only works on the first request and not subsequen requests? Other than recreating the client before each request I guess. |
Well, the last example you gave, doing a |
@stof I have the same issue but not using a stateless authentication method. |
@adrienfr I know that it also happens with a stateful authentication right now. My previous comment suggests a way to fix it. |
The change in The change from the commit broke a test where I'm using the session to store additional information and redirecting after sending a form if there is specific information in the session saved. The redirect after submitting the form now finds an „empty“ session without the needed information and redirects me somewhere else. The change in order of the if-statement fixes this. |
@sinansoezen, i was aware that my changes was not correct in the framework.yml any way. the In my case i was using multiple Firewalls in the security.yml and i was also logging in from both of them (one used for normal login, second one is used for API services). Results: i changed my custom login to login only from one firewall and i add to the API service login settings in security.yml |
@stof I had some free time so I tried implmenting your fix. It worked for the authentication issue, however it did cause one annoying followup issue. First here's my attempted fix:
The issue is that because a User object is retrieved before the reboot of the kernel, the user object will not have equivalence with the same object retreived after the reboot. This is an unrealistic example, but it demonstrates the issue.
Results in printing |
@stof and @nicolas-grekas do you think we could simply revert conditions such as it was before last change? if ($container->has('session')) {
$session = $container->get('session');
} elseif ($container->has('session.factory')) {
$session = $container->get('session.factory')->createSession();
} else {
return $this;
} |
+1 for a bug. Additional reproduction repo (without doctrine, tests are performed in-place via github actions) Fails with General idea - use Additional context Introduced in this PR #42979 |
Hi @nicolas-grekas and @stof, I submitted a PR to fix this |
I was able to workaround the issue like this replace the second loginUser:
with this:
not optimal but that seems to be the smallest change to keep existing tests working |
Thank you @guillaumesmo Workaround confirmed Philosoft/symfony-login-as-bug#5 |
… (wouterj) This PR was merged into the 5.3 branch. Discussion ---------- [FrameworkBundle] Use correct cookie domain in loginUser() | Q | A | ------------- | --- | Branch? | 5.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #43266 | License | MIT | Doc PR | Upon each request, we parse the cookie header from the response. This means that after a first request in the test, the session cookie has a domain (localhost), instead of `''`. This breaks calling `loginUser()` with another user for a subsequent test. This PR fixes this by discovering if there are already session cookies set for a specific domain, and then overriding that session. Commits ------- 52d27f7 [FrameworkBundle] Use correct cookie domain in loginUser()
The ordering of this is still a problem I think, if I log a user in and then set a session variable the user is logged out as the session is destroyed. Shouldn't this be corrected so that an existing session is maintained? |
Does it still work? I have this problem reproduced. After the first request, the token is reset. I traced where this happens, it is reset to |
The same issue as @andreymukha |
Symfony version(s) affected: 5.3.7
Description
When calling multiple subsequent requests on the same instance of KernelBrowser, only the first request will have the proper authentication. Upon the 2nd request, the TokenStorage will be reinitialized and will have lost the token, meaning if the user needs to be authorized, the request will result in a 403 Access Denied response.
How to reproduce
I have a Controller function, which I'm trying to write a test for:
With this test I'm trying to do 2 requests and compare them
Possible Solution
I've tried:
loginUser
before everyrequest()
None of these work.
I realize this might not be the best way to write a test, and we should be comparing to some static test fixture or something. I'll grant that point, but I've just been trying to migrate us over to using the
loginUser()
function on KernelBrowser, because it's prefereable to our old method of using custom Authenticators which only work on test env. We have dozens of tests written in this format, and I still don't think that this should be the desire functionality.Finally, I also realize that this might be an error in some other part of our configuration and any help working out what I've messed up would be a huge help.
The text was updated successfully, but these errors were encountered: