-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Fix logout #24805
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 logout #24805
Conversation
MatTheCat
commented
Nov 3, 2017
•
edited
Loading
edited
Q | A |
---|---|
Branch? | 2.7 |
Bug fix? | yes |
New feature? | no |
BC breaks? | no |
Deprecations? | no |
Tests pass? | no |
Fixed tickets | #6751, #7104 |
License | MIT |
|
|
||
$listener->handle($event); | ||
|
||
$hasResponse = $event->hasResponse(); |
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.
this means that it won't stop at the first listener setting the response anymore, allowing others to set the response
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.
Nope only LogoutListener
can override the response if it has been set (see https://github.com/symfony/symfony/pull/24805/files#diff-31ca8a8ce837591218082b00363149fcR65). And handle
is called so #7104 (comment) doesn't apply.
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.
Can you add a test case for this? with multiple listeners if possible
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.
I'll try but I don't know how to do it yet
@@ -359,6 +358,11 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a | |||
// Access listener | |||
$listeners[] = new Reference('security.access_listener'); | |||
|
|||
// Logout listener | |||
if (isset($logoutListener)) { |
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.
comment should be removed (low value)
the "isset" shold be replaced by null !== $logoutListener
(which implies setting the var to null when appropriate)
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.
Done
I guess |
Is there something missing for this PR to be merged? |
@@ -359,6 +360,10 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a | |||
// Access listener | |||
$listeners[] = new Reference('security.access_listener'); | |||
|
|||
if (null !== $logoutListenerId) { |
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.
Can't we just move the whole block that starts with if (isset($firewall['logout'])) {
here?
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.
Nope because factories rely on the definition being in the container so we must create it before but still register last.
@@ -285,16 +285,20 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a | |||
$listeners[] = new Reference($this->createContextListener($container, $contextKey)); | |||
} | |||
|
|||
// Determine default entry point | |||
$configuredEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null; |
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.
should probably be moved back as this is not needed
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.
Done
break; | ||
} elseif ($hasResponse) { |
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.
just if
as the previous if
stops the execution path with break
already.
@@ -53,13 +54,21 @@ public function onKernelRequest(GetResponseEvent $event) | |||
$exceptionListener->register($this->dispatcher); | |||
} | |||
|
|||
$hasResponse = false; |
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.
You don't need to create this variable. Just use $event->hasResponse()
in the right place.
Note that this will defeat the lazy-loading added in 3.4, as the loop will always iterate until it reaches the logout listener, and it is at the end. |
@chalasr @nicolas-grekas @stof @xabbuh I tried to exclude the logout listener from others to allow lazy-loading. I guess it introduced BC breaks so I would like you to review this. |
I don't understand why tests fail on PHP > 7.0, seems like a routing issue... Tests pass on my computer with PHP 7.1.12 |
Should I duplicate this PR to get more visibility? The logout listener never did work so I thought this would have got more attention. |
@MatTheCat No need for reopening a new one. |
I rebased one last time. People impacted by this issue will have to disable |
|
||
$this->assertNull($cookieJar->get('REMEMBERME')); | ||
} | ||
} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
yea, SecurityBundle's |
@@ -21,16 +21,19 @@ | |||
interface FirewallMapInterface | |||
{ | |||
/** | |||
* Returns the authentication listeners, and the exception listener to use | |||
* for the given request. | |||
* Returns the authentication listeners, the exception listener and the logout |
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.
just chatted a bit with @nicolas-grekas, let's revert the interface changes now (changelog update not needed anymore), we need to change this on 4.1 with proper deprecation.
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.
agreed: should be reverted and reintroduced in 4.1 with a deprecation notice
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.
okay done
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.
👍
After merging this (and once it is propagated until master), we should get another PR against master to deprecate the case of returning only 2 elements in the firewall map. This can be checked in the Firewall class. |
Thank you @MatTheCat. |
This PR was squashed before being merged into the 2.7 branch (closes #24805). Discussion ---------- [Security] Fix logout | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | no | Fixed tickets | #6751, #7104 | License | MIT Commits ------- 9e88eb5 [Security] Fix logout
I'll take care of the master PR. |
$listener->handle($event); | ||
|
||
if ($event->hasResponse()) { | ||
break; | ||
} | ||
} | ||
|
||
if (null !== $logoutListener) { | ||
$logoutListener->handle($event); |
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.
😍
Yay thanks! |
|
||
public function __construct(array $listeners, ExceptionListener $exceptionListener = null) | ||
public function __construct(array $listeners, ExceptionListener $exceptionListener = null, LogoutListener $logoutListener = null) |
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.
fun fact: on 3.4 & up, this class already has a 3rd argument: FirewallConfig $config
To prevent any funnier things, I suggest adding this argument in 2.7 (but ignoring its value).
WDYT? Any better idea?
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.
Can we do this on concerned branches only?
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.
we could change for a setter on 2.7, not sure it's better. Here is what you propose #27280
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.
I finally managed to merge, see 86a9c73#diff-cf0390616c24425d612bcf9ee1555111
@chalasr when doing your PR against master, please also deprecate passing a FirewallConfig as 3rd arg there.
… deprecations (chalasr) This PR was merged into the 4.2-dev branch. Discussion ---------- [Security][SecurityBundle] FirewallMap/FirewallContext deprecations | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes/no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> Next to #24805. Commits ------- a71ba78 [Security][SecurityBundle] FirewallMap/FirewallContext deprecations