From ee54bfa6462ba328be02b093ffb59796b9eaff07 Mon Sep 17 00:00:00 2001 From: Mathieu Lechat Date: Fri, 6 Apr 2018 16:49:51 +0200 Subject: [PATCH] [Security] Make security.providers optional --- .../DependencyInjection/MainConfiguration.php | 1 - .../DependencyInjection/SecurityExtension.php | 3 + .../Resources/config/security.xml | 4 ++ .../MissingUserProviderBundle.php | 18 ++++++ .../Functional/MissingUserProviderTest.php | 29 ++++++++++ .../app/MissingUserProvider/bundles.php | 20 +++++++ .../app/MissingUserProvider/config.yml | 7 +++ .../app/MissingUserProvider/routing.yml | 2 + .../Core/User/MissingUserProvider.php | 55 +++++++++++++++++++ 9 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/MissingUserProviderBundle/MissingUserProviderBundle.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/routing.yml create mode 100644 src/Symfony/Component/Security/Core/User/MissingUserProvider.php diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 7ec0eef04c47..a2feb22c8e17 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -314,7 +314,6 @@ private function addProvidersSection(ArrayNodeDefinition $rootNode) ), 'my_entity_provider' => array('entity' => array('class' => 'SecurityBundle:User', 'property' => 'username')), )) - ->isRequired() ->requiresAtLeastOneElement() ->useAttributeAsKey('name') ->prototype('array') diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 88ab77577041..f2a85f128a1e 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -422,6 +422,9 @@ private function createAuthenticationListeners($container, $id, $firewall, &$aut $userProvider = null; } elseif ($defaultProvider) { $userProvider = $defaultProvider; + } elseif (empty($providerIds)) { + $userProvider = sprintf('security.user.provider.missing.%s', $key); + $container->setDefinition($userProvider, (new ChildDefinition('security.user.provider.missing'))->replaceArgument(0, $id)); } else { throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" listener on "%s" firewall is ambiguous as there is more than one registered provider.', $key, $id)); } diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 2659619d49e8..dfc2bea84ea3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -166,6 +166,10 @@ + + + + The "%service_id%" service is deprecated since Symfony 4.1. diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/MissingUserProviderBundle/MissingUserProviderBundle.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/MissingUserProviderBundle/MissingUserProviderBundle.php new file mode 100644 index 000000000000..666ab9b86748 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/MissingUserProviderBundle/MissingUserProviderBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\MissingUserProviderBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class MissingUserProviderBundle extends Bundle +{ +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php new file mode 100644 index 000000000000..f1efe6492821 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional; + +class MissingUserProviderTest extends WebTestCase +{ + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage "default" firewall requires a user provider but none was defined. + */ + public function testUserProviderIsNeeded() + { + $client = $this->createClient(array('test_case' => 'MissingUserProvider', 'root_config' => 'config.yml')); + + $client->request('GET', '/', array(), array(), array( + 'PHP_AUTH_USER' => 'username', + 'PHP_AUTH_PW' => 'pa$$word', + )); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php new file mode 100644 index 000000000000..f902d2e3816a --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\MissingUserProviderBundle\MissingUserProviderBundle; +use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; + +return array( + new FrameworkBundle(), + new SecurityBundle(), + new MissingUserProviderBundle(), +); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml new file mode 100644 index 000000000000..501a673b4fde --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml @@ -0,0 +1,7 @@ +imports: + - { resource: ./../config/framework.yml } + +security: + firewalls: + default: + http_basic: ~ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/routing.yml new file mode 100644 index 000000000000..25e4f80f3275 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/routing.yml @@ -0,0 +1,2 @@ +home: + path: / diff --git a/src/Symfony/Component/Security/Core/User/MissingUserProvider.php b/src/Symfony/Component/Security/Core/User/MissingUserProvider.php new file mode 100644 index 000000000000..9605cf3168ec --- /dev/null +++ b/src/Symfony/Component/Security/Core/User/MissingUserProvider.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * MissingUserProvider is a dummy user provider used to throw proper exception + * when a firewall requires a user provider but none was defined. + * + * @internal + */ +class MissingUserProvider implements UserProviderInterface +{ + /** + * @param string $firewall the firewall missing a provider + */ + public function __construct(string $firewall) + { + throw new InvalidConfigurationException(sprintf('"%s" firewall requires a user provider but none was defined.', $firewall)); + } + + /** + * {@inheritdoc} + */ + public function loadUserByUsername($username) + { + throw new \BadMethodCallException(); + } + + /** + * {@inheritdoc} + */ + public function refreshUser(UserInterface $user) + { + throw new \BadMethodCallException(); + } + + /** + * {@inheritdoc} + */ + public function supportsClass($class) + { + throw new \BadMethodCallException(); + } +}