8000 bug #12296 [SecurityBundle] Authentication entry point is only regist… · symfony/symfony@226b0ce · GitHub
[go: up one dir, main page]

Skip to content

Commit 226b0ce

Browse files
committed
bug #12296 [SecurityBundle] Authentication entry point is only registered with firewall exception listener, not with authentication listeners (rjkip)
This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #12296). Discussion ---------- [SecurityBundle] Authentication entry point is only registered with firewall exception listener, not with authentication listeners | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | when relying on this configuration behaviour | Deprecations? | no | Tests pass? | yes | Fixed tickets | #12261 | License | MIT | Doc PR | — See #12261. I configured a different firewall entry point for one firewall. However, when authentication had to be performed, it still called BasicAuthenticationEntryPoint::start() instead of my service's start(). My service was instantiated, yet never used. The issue appears to be that the entry point is registered with the firewall's exception listener, but not with the BasicAuthenticationListener. This means that when the BasicAuthenticationListener determines the user has provided wrong credentials, BasicAuthenticationEntryPoint is still used. Only in case of an exception would my entry point service be used. In my opinion, this is not correct behaviour. Can someone confirm this? Are there currently tests that pertain to the `entry_point` configuration on which I can base a test? --- Test setup: ```yaml # security.yml security: firewalls: api: pattern: ^/api/ http_basic: ~ entry_point: my.service default: anonymous: ~ ``` Commits ------- 92c8dfb [SecurityBundle] Authentication entry point is only registered with firewall exception listener, not with authentication listeners
2 parents b9425f0 + 92c8dfb commit 226b0ce

File tree

9 files changed

+179
-8
lines changed

9 files changed

+179
-8
lines changed

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,11 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
333333
;
334334
}
335335

336+
// Determine default entry point
337+
$defaultEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null;
338+
336339
// Authentication listeners
337-
list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider);
340+
list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $defaultEntryPoint);
338341

339342
$listeners = array_merge($listeners, $authListeners);
340343

@@ -346,11 +349,6 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
346349
// Access listener
347350
$listeners[] = new Reference('security.access_listener');
348351

349-
// Determine default entry point
350-
if (isset($firewall['entry_point'])) {
351-
$defaultEntryPoint = $firewall['entry_point'];
352-
}
353-
354352
// Exception listener
355353
$exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $defaultEntryPoint));
356354

@@ -370,11 +368,10 @@ private function createContextListener($container, $contextKey)
370368
return $this->contextListeners[$contextKey] = $listenerId;
371369
}
372370

373-
private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider)
371+
private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider, $defaultEntryPoint)
374372
{
375373
$listeners = array();
376374
$hasListeners = false;
377-
$defaultEntryPoint = null;
378375

379376
foreach ($this->listenerPositions as $position) {
380377
foreach ($this->factories[$position] as $factory) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\DependencyInjection;
13+
14+
use Symfony\Component\Config\FileLocator;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
17+
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
18+
19+
class FirewallEntryPointExtension extends Extension
20+
{
21+
public function load(array $config, ContainerBuilder $container)
22+
{
23+
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
24+
$loader->load('services.xml');
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle;
13+
14+
use Symfony\Component\HttpKernel\Bundle\Bundle;
15+
16+
class FirewallEntryPointBundle extends Bundle
17+
{
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5+
<services>
6+
<service id="firewall_entry_point.entry_point.stub"
7+
class="Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\Security\EntryPointStub"
8+
/>
9+
</services>
10+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\Security;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
17+
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
18+
19+
class EntryPointStub implements AuthenticationEntryPointInterface
20+
{
21+
const RESPONSE_TEXT = '2be8e651259189d841a19eecdf37e771e2431741';
22+
23+
public function start(Request $request, AuthenticationException $authException = null)
24+
{
25+
return new Response(self::RESPONSE_TEXT);
26+
}
27+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\SecurityBundle\Tests\Functional;
13+
14+
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\Security\EntryPointStub;
15+
16+
/**
17+
* @group functional
18+
*/
19+
class FirewallEntryPointTest extends WebTestCase
20+
{
21+
public function testItUsesTheConfiguredEntryPointWhenUsingUnknownCredentials()
22+
{
23+
$client = $this->createClient(array('test_case' => 'FirewallEntryPoint'));
24+
$client->insulate();
25+
26+
$client->request('GET', '/secure/resource', array(), array(), array(
27+
'PHP_AUTH_USER' => 'unknown',
28+
'PHP_AUTH_PW' => 'credentials',
29+
));
30+
31+
$this->assertEquals(
32+
EntryPointStub::RESPONSE_TEXT,
33+
$client->getResponse()->getContent(),
34+
"Custom entry point wasn't started"
35+
);
36+
}
37+
38+
protected function setUp()
39+
{
40+
parent::setUp();
41+
42+
$this->deleteTmpDir('FirewallEntryPoint');
43+
}
44+
45+
protected function tearDown()
46+
{
47+
parent::tearDown();
48+
49+
$this->deleteTmpDir('FirewallEntryPoint');
50+
}
51+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
return array(
4+
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
5+
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
6+
new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\FirewallEntryPointBundle(),
7+
);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
framework:
2+
secret: test
3+
csrf_protection:
4+
enabled: true
5+
router: { resource: "%kernel.root_dir%/%kernel.test_case%/routing.yml" }
6+
validation: { enabled: true, enable_annotations: true }
7+
form: ~
8+
test: ~
9+
default_locale: en
10+
session:
11+
storage_id: session.storage.mock_file
12+
profiler: { only_exceptions: false }
13+
14+
services:
15+
logger: { class: Symfony\Component\HttpKernel\Log\NullLogger }
16+
17+
security:
18+
firewalls:
19+
secure:
20+
pattern: ^/secure/
21+
http_basic: { realm: "Secure Gateway API" }
22+
entry_point: firewall_entry_point.entry_point.stub
23+
default:
24+
anonymous: ~
25+
access_control:
26+
- { path: ^/secure/, roles: ROLE_SECURE }
27+
providers:
28+
in_memory:
29+
memory:
30+
users:
31+
john: { password: doe, roles: [ROLE_SECURE] }
32+
encoders:
33+
Symfony\Component\Security\Core\User\User: plaintext
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
secure_resource:
2+
path: /secure/resource

0 commit comments

Comments
 (0)
0