-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Deprecated not being logged out after user change #23882
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,13 +37,13 @@ | |
class ContextListener implements ListenerInterface | ||
{ | ||
private $tokenStorage; | ||
private $contextKey; | ||
private $sessionKey; | ||
private $logger; | ||
private $userProviders; | ||
private $dispatcher; | ||
private $registered; | ||
private $trustResolver; | ||
private $logoutOnUserChange = false; | ||
|
||
/** | ||
* @param TokenStorageInterface $tokenStorage | ||
|
@@ -61,13 +61,22 @@ public function __construct(TokenStorageInterface $tokenStorage, $userProviders, | |
|
||
$this->tokenStorage = $tokenStorage; | ||
$this->userProviders = $userProviders; | ||
$this->contextKey = $contextKey; | ||
$this->sessionKey = '_security_'.$contextKey; | ||
$this->logger = $logger; | ||
$this->dispatcher = $dispatcher; | ||
$this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class); | ||
} | ||
|
||
/** | ||
* Enables deauthentication during refreshUser when the user has changed. | ||
* | ||
* @param bool $logoutOnUserChange | ||
*/ | ||
public function setLogoutOnUserChange($logoutOnUserChange) | ||
{ | ||
$this->logoutOnUserChange = (bool) $logoutOnUserChange; | ||
} | ||
|
||
/** | ||
* Reads the Security Token from the session. | ||
* | ||
|
@@ -122,14 +131,14 @@ public function onKernelResponse(FilterResponseEvent $event) | |
return; | ||
} | ||
|
||
if (!$event->getRequest()->hasSession()) { | ||
$request = $event->getRequest(); | ||
|
||
if (!$request->hasSession()) { | ||
return; | ||
} | ||
|
||
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse')); | ||
$this->registered = false; | ||
|
||
$request = $event->getRequest(); | ||
$session = $request->getSession(); | ||
|
||
if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) { | ||
|
@@ -172,6 +181,19 @@ protected function refreshUser(TokenInterface $token) | |
$refreshedUser = $provider->refreshUser($user); | ||
$token->setUser($refreshedUser); | ||
|
||
// tokens can be deauthenticated if the user has been changed. | ||
if (!$token->isAuthenticated()) { | ||
if ($this->logoutOnUserChange) { | ||
if (null !== $this->logger) { | ||
$this->logger->debug('Token was deauthenticated after trying to refresh it.', array('username' => $refreshedUser->getUsername(), 'provider' => get_class($provider))); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@trigger_error('Refreshing a deauthenticated user is deprecated as of 3.4 and will trigger a logout in 4.0.', E_USER_DEPRECATED); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a changelog+upgrade entries would be great There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will add them as soon as I know how to proceed with the actual logging out users, as this might need more additions to the changelog and upgrade entries 👍 |
||
} | ||
|
||
if (null !== $this->logger) { | ||
$context = array('provider' => get_class($provider), 'username' => $refreshedUser->getUsername()); | ||
|
||
|
@@ -198,7 +220,7 @@ protected function refreshUser(TokenInterface $token) | |
} | ||
|
||
if ($userNotFoundByProvider) { | ||
return; | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be reverted as it should be applied to the 2.7 branch. But it is worth a dedicated PR on the whole codebase. Related to #17201. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will fix |
||
} | ||
|
||
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', get_class($user))); | ||
|
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 think we need to deprecate the constructor argument if the class doesn't need it anymore. That can be done in another PR, could you revert this change (with the property removal)?
Uh oh!
There was an error while loading. Please reload this page.
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.
It's still used for the
sessionKey
below. Only the property is removed because it's not used. (However again, it could have been done on the 2.7 branch ^^)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.
Correct, I've merely removed the property because the property wasn't used anymore. If desired, I can change this in a lower branch instead.
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.
@iltar that would be nice
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.
see #24329