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

Skip to content

Commit d65695d

Browse files
committed
[SecurityBundle] Link UserProviderListener to correct firewall dispatcher
1 parent 0f4cbc0 commit d65695d

File tree

8 files changed

+186
-9
lines changed

8 files changed

+186
-9
lines changed

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SecurityController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class SecurityController implements ContainerAwareInterface
1919
{
2020
use ContainerAwareTrait;
2121

22+
public function checkAction()
23+
{
24+
return new Response('OK');
25+
}
26+
2227
public function profileAction()
2328
{
2429
return new Response('Welcome '.$this->container->get('security.token_storage')->getToken()->getUsername().'!');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Security;
13+
14+
use Symfony\Component\HttpFoundation\RedirectResponse;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
18+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19+
use Symfony\Component\Security\Core\Security;
20+
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
21+
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
22+
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
23+
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
24+
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
25+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
26+
27+
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
28+
{
29+
use TargetPathTrait;
30+
31+
/** @var UrlGeneratorInterface */
32+
private $urlGenerator;
33+
34+
public function __construct(UrlGeneratorInterface $urlGenerator)
35+
{
36+
$this->urlGenerator = $urlGenerator;
37+
}
38+
39+
public function authenticate(Request $request): PassportInterface
40+
{
41+
$username = $request->request->get('_username', '');
42+
43+
$request->getSession()->set(Security::LAST_USERNAME, $username);
44+
45+
return new Passport(
46+
new UserBadge($username),
47+
new PasswordCredentials($request->request->get('_password', '')),
48+
[]
49+
);
50+
}
51+
52+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $firewallName): ?Response
53+
{
54+
return new RedirectResponse('/'.$firewallName.'/user_profile');
55+
}
56+
57+
protected function getLoginUrl(Request $request): string
58+
{
59+
return str_contains($request->getUri(), 'custom') ? '/custom/login/check' : '/main/login/check';
60+
}
61+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
/**
15+
* @group functional
16+
*/
17+
class SecurityAuthenticatorManagerTest extends AbstractWebTestCase
18+
{
19+
/**
20+
* @dataProvider getUsers
21+
*/
22+
public function testLoginUsersFromDifferentFirewalls(string $username, string $firewallContext)
23+
{
24+
$client = $this->createClient(['test_case' => 'SecurityAuthenticatorManager', 'root_config' => 'config.yml']);
25+
26+
$client->request('POST', '/'.$firewallContext.'/login/check', [
27+
'_username' => $username,
28+
'_password' => 'the-password',
29+
]);
30+
$this->assertResponseRedirects('/'.$firewallContext.'/user_profile');
31+
32+
$client->request('GET', '/'.$firewallContext.'/user_profile');
33+
$this->assertEquals('Welcome '.$username.'!', $client->getResponse()->getContent());
34+
}
35+
36+
public function getUsers()
37+
{
38+
yield ['the-username', 'main'];
39+
yield ['other-username', 'custom'];
40+
}
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
14+
use Symfony\Bundle\SecurityBundle\SecurityBundle;
15+
16+
return [
17+
new FrameworkBundle(),
18+
new SecurityBundle(),
19+
new TestBundle(),
20+
];
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
imports:
2+
- { resource: ./../config/default.yml }
3+
- { resource: services.yml }
4+
5+
security:
6+
enable_authenticator_manager: true
7+
8+
encoders:
9+
Symfony\Component\Security\Core\User\User: 'plaintext'
10+
11+
providers:
12+
main:
13+
memory:
14+
users:
15+
the-username: { password: the-password, roles: ['ROLE_FOO'] }
16+
custom:
17+
memory:
18+
users:
19+
other-username: { password: the-password, roles: ['ROLE_FOO'] }
20+
21+
firewalls:
22+
main:
23+
pattern: ^/main
24+
custom_authenticator: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Security\LoginFormAuthenticator
25+
provider: main
26+
custom:
27+
pattern: ^/custom
28+
custom_authenticator: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Security\LoginFormAuthenticator
29+
provider: custom
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
security_login:
2+
path: /main/login/check
3+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::checkAction }
4+
5+
security_custom_login:
6+
path: /custom/login/check
7+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::checkAction }
8+
9+
security_profile:
10+
path: /main/user_profile
11+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction }
12+
13+
security_custom_profile:
14+
path: /custom/user_profile
15+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
_defaults:
3+
public: true
4+
5+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Security\LoginFormAuthenticator:
6+
arguments: ['@router']

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,14 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
339339

340340
$config->replaceArgument(4, $firewall['stateless']);
341341

342+
// Register Firewall-specific event dispatcher
343+
$firewallEventDispatcherId = 'security.event_dispatcher.'.$id;
344+
$container->register($firewallEventDispatcherId, EventDispatcher::class);
345+
346+
// Register listeners
347+
$listeners = [];
348+
$listenerKeys = [];
349+
342350
// Provider id (must be configured explicitly per firewall/authenticator if more than one provider is set)
343351
$defaultProvider = null;
344352
if (isset($firewall['provider'])) {
@@ -349,7 +357,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
349357

350358
if ($this->authenticatorManagerEnabled) {
351359
$container->setDefinition('security.listener.'.$id.'.user_provider', new ChildDefinition('security.listener.user_provider.abstract'))
352-
->addTag('kernel.event_listener', ['event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport'])
360+
->addTag('kernel.event_listener', ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport'])
353361
->replaceArgument(0, new Reference($defaultProvider));
354362
}
355363
} elseif (1 === \count($providerIds)) {
@@ -358,14 +366,6 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
358366

359367
$config->replaceArgument(5, $defaultProvider);
360368

361-
// Register Firewall-specific event dispatcher
362-
$firewallEventDispatcherId = 'security.event_dispatcher.'.$id;
363-
$container->register($firewallEventDispatcherId, EventDispatcher::class);
364-
365-
// Register listeners
366-
$listeners = [];
367-
$listenerKeys = [];
368-
369369
// Channel listener
370370
$listeners[] = new Reference('security.channel_listener');
371371

0 commit comments

Comments
 (0)