bug #18425 [Security] Fixed SwitchUserListener when exiting an impersonation with AnonymousToken (lyrixx)
This PR was merged into the 2.3 branch.
Discussion
----------
[Security] Fixed SwitchUserListener when exiting an impersonation with AnonymousToken
| Q | A
| ------------- | ---
| Branch? | 2.3
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
If you configure a firewall with switch user with `role: IS_AUTHENTICATED_ANONYMOUSLY` it's impossible to exit the
impersonation because the next line `$this->provider->refreshUser($original->getUser())` will fail. It fails because `RefreshUser`
expects an instance of `UserInterface` and here it's a string.
Therefore, it does not make sense to refresh an Anonymous Token, right ?
Commits
-------
59fea72
[Security] Fixed SwitchUserListener when exiting an impersonication with AnonymousToken
This commit is contained in:
commit
5b6da77a96
@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
|
|||||||
|
|
||||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
use Symfony\Component\Security\Core\SecurityContextInterface;
|
use Symfony\Component\Security\Core\SecurityContextInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
||||||
@ -162,7 +163,7 @@ class SwitchUserListener implements ListenerInterface
|
|||||||
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
|
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->dispatcher) {
|
if (null !== $this->dispatcher && $original->getUser() instanceof UserInterface) {
|
||||||
$user = $this->provider->refreshUser($original->getUser());
|
$user = $this->provider->refreshUser($original->getUser());
|
||||||
$switchEvent = new SwitchUserEvent($request, $user);
|
$switchEvent = new SwitchUserEvent($request, $user);
|
||||||
$this->dispatcher->dispatch(SecurityEvents::SWITCH_USER, $switchEvent);
|
$this->dispatcher->dispatch(SecurityEvents::SWITCH_USER, $switchEvent);
|
||||||
|
@ -149,6 +149,54 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$listener->handle($this->event);
|
$listener->handle($this->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testExitUserDoesNotDispatchEventWithStringUser()
|
||||||
|
{
|
||||||
|
$originalUser = 'anon.';
|
||||||
|
$refreshedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
|
||||||
|
$this
|
||||||
|
->userProvider
|
||||||
|
->expects($this->never())
|
||||||
|
->method('refreshUser');
|
||||||
|
$originalToken = $this->getToken();
|
||||||
|
$originalToken
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUser')
|
||||||
|
->willReturn($originalUser);
|
||||||
|
$role = $this
|
||||||
|
->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$role
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getSource')
|
||||||
|
->willReturn($originalToken);
|
||||||
|
$this
|
||||||
|
->securityContext
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getToken')
|
||||||
|
->willReturn($this->getToken(array($role)));
|
||||||
|
$this
|
||||||
|
->request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('get')
|
||||||
|
->with('_switch_user')
|
||||||
|
->willReturn('_exit');
|
||||||
|
$this
|
||||||
|
->request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUri')
|
||||||
|
->willReturn('/');
|
||||||
|
|
||||||
|
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||||
|
$dispatcher
|
||||||
|
->expects($this->never())
|
||||||
|
->method('dispatch')
|
||||||
|
;
|
||||||
|
|
||||||
|
$listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
|
||||||
|
$listener->handle($this->event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
|
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user