Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0285bfd

Browse filesBrowse files
committed
bug #8997 [Security] Fixed problem with losing ROLE_PREVIOUS_ADMIN role. (pawaclawczyk)
This PR was squashed before being merged into the 2.3 branch (closes #8997). Discussion ---------- [Security] Fixed problem with losing ROLE_PREVIOUS_ADMIN role. <table> <tr> <td><b>Q</b></td> <td><b>A</b></td> </tr> <tr> <td>Bug fix?</td> <td>yes</td> </tr> <tr> <td>New feature</td> <td>no</td> </tr> <tr> <td>BC breaks?</td> <td>no</td> </tr> <tr> <td>Deprecations?</td> <td>no</td> </tr> <tr> <td>Tests pass?</td> <td>yes</td> </tr> <tr> <td>Fixed tickets</td> <td>#3085, #8974</td> </tr> <tr> <td>License</td> <td>MIT</td> </tr> <tr> <td>Doc PR</td> <td>n/a</td> </tr> </table> Problem occurs while user is impersonated. Authentication process generates new token and doeas not preserve role ```ROLE_PREVIOUS_ADMIN```. Ex. when parameter ```security.always_authenticate_before_granting``` is enabled. Commits ------- a7baa3b [Security] Fixed problem with losing ROLE_PREVIOUS_ADMIN role.
2 parents be01e34 + a7baa3b commit 0285bfd
Copy full SHA for 0285bfd

File tree

Expand file treeCollapse file tree

2 files changed

+68
-2
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+68
-2
lines changed

‎src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php
+25-1Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
2020
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
2121
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
22+
use Symfony\Component\Security\Core\Role\SwitchUserRole;
2223

2324
/**
2425
* UserProviderInterface retrieves users for UsernamePasswordToken tokens.
@@ -92,7 +93,7 @@ public function authenticate(TokenInterface $token)
9293
throw $e;
9394
}
9495

95-
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
96+
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
9697
$authenticatedToken->setAttributes($token->getAttributes());
9798

9899
return $authenticatedToken;
@@ -106,6 +107,29 @@ public function supports(TokenInterface $token)
106107
return $token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey();
107108
}
108109

110+
/**
111+
* Retrieves roles from user and appends SwitchUserRole if original token contained one.
112+
*
113+
* @param UserInterface $user The user
114+
* @param TokenInterface $token The token
115+
*
116+
* @return Role[] The user roles
117+
*/
118+
private function getRoles(UserInterface $user, TokenInterface $token)
119+
{
120+
$roles = $user->getRoles();
121+
122+
foreach ($token->getRoles() as $role) {
123+
if ($role instanceof SwitchUserRole) {
124+
$roles[] = $role;
125+
126+
break;
127+
}
128+
}
129+
130+
return $roles;
131+
}
132+
109133
/**
110134
* Retrieves the user from an implementation-specific location.
111135
*

‎src/Symfony/Component/Security/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php
+43-1Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider;
1515
use Symfony\Component\Security\Core\Role\Role;
16+
use Symfony\Component\Security\Core\Role\SwitchUserRole;
1617
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1718

1819
class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
@@ -172,6 +173,11 @@ public function testAuthenticate()
172173
->will($this->returnValue('foo'))
173174
;
174175

176+
$token->expects($this->once())
177+
->method('getRoles')
178+
->will($this->returnValue(array()))
179+
;
180+
175181
$authToken = $provider->authenticate($token);
176182

177183
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken);
@@ -181,9 +187,45 @@ public function testAuthenticate()
181187
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
182188
}
183189

190+
public function testAuthenticateWithPreservingRoleSwitchUserRole()
191+
{
192+
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
193+
$user->expects($this->once())
194+
->method('getRoles')
195+
->will($this->returnValue(array('ROLE_FOO')))
196+
;
197+
198+
$provider = $this->getProvider();
199+
$provider->expects($this->once())
200+
->method('retrieveUser')
201+
->will($this->returnValue($user))
202+
;
203+
204+
$token = $this->getSupportedToken();
205+
$token->expects($this->once())
206+
->method('getCredentials')
207+
->will($this->returnValue('foo'))
208+
;
209+
210+
$switchUserRole = new SwitchUserRole('foo', $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
211+
$token->expects($this->once())
212+
->method('getRoles')
213+
->will($this->returnValue(array($switchUserRole)))
214+
;
215+
216+
$authToken = $provider->authenticate($token);
217+
218+
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken);
219+
$this->assertSame($user, $authToken->getUser());
220+
$this->assertContains(new Role('ROLE_FOO'), $authToken->getRoles(), '', false, false);
221+
$this->assertContains($switchUserRole, $authToken->getRoles());
222+
$this->assertEquals('foo', $authToken->getCredentials());
223+
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
224+
}
225+
184226
protected function getSupportedToken()
185227
{
186-
$mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', array('getCredentials', 'getProviderKey'), array(), '', false);
228+
$mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', array('getCredentials', 'getProviderKey', 'getRoles'), array(), '', false);
187229
$mock
188230
->expects($this->any())
189231
->method('getProviderKey')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.