feature #24388 [Security] Look at headers for switch_user username (chalasr)
This PR was merged into the 3.4 branch.
Discussion
----------
[Security] Look at headers for switch_user username
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #24260
| License | MIT
| Doc PR | n/a
Allowing `switch_user.parameter` config node to be a header name.
It's supported by SwitchUserStatelessBundle and I think it makes sense.
Forgotten in #24260 so targets 3.4 but not a blocker.
Commits
-------
3c801951c8
[Security] Look at headers for switch user username parameter
This commit is contained in:
commit
0c8043a7d6
@ -54,7 +54,7 @@ class SwitchUserTest extends WebTestCase
|
|||||||
public function testSwitchUserStateless()
|
public function testSwitchUserStateless()
|
||||||
{
|
{
|
||||||
$client = $this->createClient(array('test_case' => 'JsonLogin', 'root_config' => 'switchuser_stateless.yml'));
|
$client = $this->createClient(array('test_case' => 'JsonLogin', 'root_config' => 'switchuser_stateless.yml'));
|
||||||
$client->request('POST', '/chk', array('_switch_user' => 'dunglas'), array(), array('CONTENT_TYPE' => 'application/json'), '{"user": {"login": "user_can_switch", "password": "test"}}');
|
$client->request('POST', '/chk', array(), array(), array('HTTP_X_SWITCH_USER' => 'dunglas', 'CONTENT_TYPE' => 'application/json'), '{"user": {"login": "user_can_switch", "password": "test"}}');
|
||||||
$response = $client->getResponse();
|
$response = $client->getResponse();
|
||||||
|
|
||||||
$this->assertInstanceOf(JsonResponse::class, $response);
|
$this->assertInstanceOf(JsonResponse::class, $response);
|
||||||
|
@ -10,4 +10,5 @@ security:
|
|||||||
firewalls:
|
firewalls:
|
||||||
main:
|
main:
|
||||||
switch_user:
|
switch_user:
|
||||||
|
parameter: X-Switch-User
|
||||||
stateless: true
|
stateless: true
|
||||||
|
@ -79,16 +79,17 @@ class SwitchUserListener implements ListenerInterface
|
|||||||
public function handle(GetResponseEvent $event)
|
public function handle(GetResponseEvent $event)
|
||||||
{
|
{
|
||||||
$request = $event->getRequest();
|
$request = $event->getRequest();
|
||||||
|
$username = $request->get($this->usernameParameter) ?: $request->headers->get($this->usernameParameter);
|
||||||
|
|
||||||
if (!$request->get($this->usernameParameter)) {
|
if (!$username) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::EXIT_VALUE === $request->get($this->usernameParameter)) {
|
if (self::EXIT_VALUE === $username) {
|
||||||
$this->tokenStorage->setToken($this->attemptExitUser($request));
|
$this->tokenStorage->setToken($this->attemptExitUser($request));
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$this->tokenStorage->setToken($this->attemptSwitchUser($request));
|
$this->tokenStorage->setToken($this->attemptSwitchUser($request, $username));
|
||||||
} catch (AuthenticationException $e) {
|
} catch (AuthenticationException $e) {
|
||||||
throw new \LogicException(sprintf('Switch User failed: "%s"', $e->getMessage()));
|
throw new \LogicException(sprintf('Switch User failed: "%s"', $e->getMessage()));
|
||||||
}
|
}
|
||||||
@ -106,20 +107,21 @@ class SwitchUserListener implements ListenerInterface
|
|||||||
/**
|
/**
|
||||||
* Attempts to switch to another user.
|
* Attempts to switch to another user.
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param Request $request A Request instance
|
||||||
|
* @param string $username
|
||||||
*
|
*
|
||||||
* @return TokenInterface|null The new TokenInterface if successfully switched, null otherwise
|
* @return TokenInterface|null The new TokenInterface if successfully switched, null otherwise
|
||||||
*
|
*
|
||||||
* @throws \LogicException
|
* @throws \LogicException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
*/
|
*/
|
||||||
private function attemptSwitchUser(Request $request)
|
private function attemptSwitchUser(Request $request, $username)
|
||||||
{
|
{
|
||||||
$token = $this->tokenStorage->getToken();
|
$token = $this->tokenStorage->getToken();
|
||||||
$originalToken = $this->getOriginalToken($token);
|
$originalToken = $this->getOriginalToken($token);
|
||||||
|
|
||||||
if (false !== $originalToken) {
|
if (false !== $originalToken) {
|
||||||
if ($token->getUsername() === $request->get($this->usernameParameter)) {
|
if ($token->getUsername() === $username) {
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +135,6 @@ class SwitchUserListener implements ListenerInterface
|
|||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
$username = $request->get($this->usernameParameter);
|
|
||||||
|
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->info('Attempting to switch to user.', array('username' => $username));
|
$this->logger->info('Attempting to switch to user.', array('username' => $username));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user