Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0fb0929

Browse files
committed
context listener: hardening user provider handling
1 parent 5898ec2 commit 0fb0929

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

src/Symfony/Component/Security/Http/Firewall/ContextListener.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ protected function refreshUser(TokenInterface $token)
150150
return $token;
151151
}
152152

153+
$userNotFoundByProvider = false;
154+
153155
foreach ($this->userProviders as $provider) {
154156
try {
155157
$refreshedUser = $provider->refreshUser($user);
@@ -167,10 +169,14 @@ protected function refreshUser(TokenInterface $token)
167169
$this->logger->warning('Username could not be found in the selected user provider.', array('username' => $e->getUsername(), 'provider' => get_class($provider)));
168170
}
169171

170-
return;
172+
$userNotFoundByProvider = true;
171173
}
172174
}
173175

176+
if ($userNotFoundByProvider) {
177+
return;
178+
}
179+
174180
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', get_class($user)));
175181
}
176182
}

src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,17 @@
1717
use Symfony\Component\HttpFoundation\Session\Session;
1818
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
1919
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
20+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
2021
use Symfony\Component\HttpKernel\HttpKernelInterface;
2122
use Symfony\Component\HttpKernel\KernelEvents;
2223
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
24+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2325
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
26+
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
27+
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
28+
use Symfony\Component\Security\Core\User\User;
29+
use Symfony\Component\Security\Core\User\UserInterface;
30+
use Symfony\Component\Security\Core\User\UserProviderInterface;
2431
use Symfony\Component\Security\Http\Firewall\ContextListener;
2532
use Symfony\Component\EventDispatcher\EventDispatcher;
2633

@@ -238,6 +245,40 @@ public function testHandleRemovesTokenIfNoPreviousSessionWasFound()
238245
$listener->handle($event);
239246
}
240247

248+
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
249+
{
250+
$tokenStorage = new TokenStorage();
251+
$refreshedUser = new User('foobar', 'baz');
252+
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
253+
254+
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
255+
}
256+
257+
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
258+
{
259+
$tokenStorage = new TokenStorage();
260+
$refreshedUser = new User('foobar', 'baz');
261+
$this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
262+
263+
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
264+
}
265+
266+
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
267+
{
268+
$tokenStorage = new TokenStorage();
269+
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider()));
270+
271+
$this->assertNull($tokenStorage->getToken());
272+
}
273+
274+
/**
275+
* @expectedException \RuntimeException
276+
*/
277+
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
278+
{
279+
$this->handleEventWithPreviousSession(new TokenStorage(), array(new NotSupportingUserProvider(), new NotSupportingUserProvider()));
280+
}
281+
241282
protected function runSessionOnKernelResponse($newToken, $original = null)
242283
{
243284
$session = new Session(new MockArraySessionStorage());
@@ -265,4 +306,67 @@ protected function runSessionOnKernelResponse($newToken, $original = null)
265306

266307
return $session;
267308
}
309+
310+
private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, array $userProviders)
311+
{
312+
$session = new Session(new MockArraySessionStorage());
313+
$session->set('_security_context_key', serialize(new UsernamePasswordToken(new User('foo', 'bar'), '', 'context_key')));
314+
315+
$request = new Request();
316+
$request->setSession($session);
317+
$request->cookies->set('MOCKSESSID', true);
318+
319+
$listener = new ContextListener($tokenStorage, $userProviders, 'context_key');
320+
$listener->handle(new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
321+
}
322+
}
323+
324+
class NotSupportingUserProvider implements UserProviderInterface
325+
{
326+
public function loadUserByUsername($username)
327+
{
328+
throw new UsernameNotFoundException();
329+
}
330+
331+
public function refreshUser(UserInterface $user)
332+
{
333+
throw new UnsupportedUserException();
334+
}
335+
336+
public function supportsClass($class)
337+
{
338+
return false;
339+
}
340+
}
341+
342+
class SupportingUserProvider implements UserProviderInterface
343+
{
344+
private $refreshedUser;
345+
346+
public function __construct(User $refreshedUser = null)
347+
{
348+
$this->refreshedUser = $refreshedUser;
349+
}
350+
351+
public function loadUserByUsername($username)
352+
{
353+
}
354+
355+
public function refreshUser(UserInterface $user)
356+
{
357+
if (!$user instanceof User) {
358+
throw new UnsupportedUserException();
359+
}
360+
361+
if (null === $this->refreshedUser) {
362+
throw new UsernameNotFoundException();
363+
}
364+
365+
return $this->refreshedUser;
366+
}
367+
368+
public function supportsClass($class)
369+
{
370+
return 'Symfony\Component\Security\Core\User\User' === $class;
371+
}
268372
}

0 commit comments

Comments
 (0)