diff --git a/DependencyInjection/MainConfiguration.php b/DependencyInjection/MainConfiguration.php index b9d0a225..bd955976 100644 --- a/DependencyInjection/MainConfiguration.php +++ b/DependencyInjection/MainConfiguration.php @@ -48,24 +48,6 @@ public function getConfigTreeBuilder() $rootNode = $tb->getRootNode(); $rootNode - ->beforeNormalization() - ->ifTrue(function ($v) { - if (!isset($v['access_decision_manager'])) { - return true; - } - - if (!isset($v['access_decision_manager']['strategy']) && !isset($v['access_decision_manager']['service'])) { - return true; - } - - return false; - }) - ->then(function ($v) { - $v['access_decision_manager']['strategy'] = AccessDecisionManager::STRATEGY_AFFIRMATIVE; - - return $v; - }) - ->end() ->beforeNormalization() ->ifTrue(function ($v) { if ($v['encoders'] ?? false) { diff --git a/DependencyInjection/Security/Factory/RememberMeFactory.php b/DependencyInjection/Security/Factory/RememberMeFactory.php index de19f488..525726b0 100644 --- a/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -208,6 +208,7 @@ public function addConfiguration(NodeDefinition $node) ->requiresAtLeastOneElement() ->info('An array of properties on your User that are used to sign the remember-me cookie. If any of these change, all existing cookies will become invalid.') ->example(['email', 'password']) + ->defaultValue(['password']) ->end() ->arrayNode('token_provider') ->beforeNormalization() diff --git a/DependencyInjection/SecurityExtension.php b/DependencyInjection/SecurityExtension.php index f1ce0a9a..557134a3 100644 --- a/DependencyInjection/SecurityExtension.php +++ b/DependencyInjection/SecurityExtension.php @@ -39,6 +39,7 @@ use Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher; use Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher; use Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManager; use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder; use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder; @@ -163,7 +164,7 @@ public function load(array $configs, ContainerBuilder $container) } else { $container ->getDefinition('security.access.decision_manager') - ->addArgument($config['access_decision_manager']['strategy']) + ->addArgument($config['access_decision_manager']['strategy'] ?? AccessDecisionManager::STRATEGY_AFFIRMATIVE) ->addArgument($config['access_decision_manager']['allow_if_all_abstain']) ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']); } @@ -677,7 +678,7 @@ private function getUserProvider(ContainerBuilder $container, string $id, array return 'security.user_providers'; } - 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.', $factoryKey, $id)); + throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" %s on "%s" firewall is ambiguous as there is more than one registered provider.', $factoryKey, $this->authenticatorManagerEnabled ? 'authenticator' : 'listener', $id)); } private function createEncoders(array $encoders, ContainerBuilder $container) diff --git a/Tests/DependencyInjection/MainConfigurationTest.php b/Tests/DependencyInjection/MainConfigurationTest.php index acdfff8d..ffefe42c 100644 --- a/Tests/DependencyInjection/MainConfigurationTest.php +++ b/Tests/DependencyInjection/MainConfigurationTest.php @@ -15,6 +15,7 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManager; class MainConfigurationTest extends TestCase { @@ -113,4 +114,22 @@ public function testUserCheckers() $this->assertEquals('app.henk_checker', $processedConfig['firewalls']['stub']['user_checker']); } + + public function testConfigMergeWithAccessDecisionManager() + { + $config = [ + 'access_decision_manager' => [ + 'strategy' => AccessDecisionManager::STRATEGY_UNANIMOUS, + ], + ]; + $config = array_merge(static::$minimalConfig, $config); + + $config2 = []; + + $processor = new Processor(); + $configuration = new MainConfiguration([], []); + $processedConfig = $processor->processConfiguration($configuration, [$config, $config2]); + + $this->assertSame(AccessDecisionManager::STRATEGY_UNANIMOUS, $processedConfig['access_decision_manager']['strategy']); + } } diff --git a/Tests/DependencyInjection/SecurityExtensionTest.php b/Tests/DependencyInjection/SecurityExtensionTest.php index 3df35509..450f6644 100644 --- a/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/Tests/DependencyInjection/SecurityExtensionTest.php @@ -35,7 +35,6 @@ use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AuthenticatorInterface as GuardAuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; @@ -220,7 +219,7 @@ public function testPerListenerProvider() public function testMissingProviderForListener() { $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('Not configuring explicitly the provider for the "http_basic" listener on "ambiguous" firewall is ambiguous as there is more than one registered provider.'); + $this->expectExceptionMessage('Not configuring explicitly the provider for the "http_basic" authenticator on "ambiguous" firewall is ambiguous as there is more than one registered provider.'); $container = $this->getRawContainer(); $container->loadFromExtension('security', [ 'enable_authenticator_manager' => true, @@ -835,45 +834,6 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio } } -class NullAuthenticator implements GuardAuthenticatorInterface -{ - public function start(Request $request, AuthenticationException $authException = null) - { - } - - public function supports(Request $request) - { - } - - public function getCredentials(Request $request) - { - } - - public function getUser($credentials, UserProviderInterface $userProvider) - { - } - - public function checkCredentials($credentials, UserInterface $user) - { - } - - public function createAuthenticatedToken(UserInterface $user, string $providerKey) - { - } - - public function onAuthenticationFailure(Request $request, AuthenticationException $exception) - { - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey) - { - } - - public function supportsRememberMe() - { - } -} - class TestUserChecker implements UserCheckerInterface { public function checkPreAuth(UserInterface $user) diff --git a/Tests/Functional/Bundle/RememberMeBundle/Security/UserChangingUserProvider.php b/Tests/Functional/Bundle/RememberMeBundle/Security/UserChangingUserProvider.php index a5306b6b..f2eebacf 100644 --- a/Tests/Functional/Bundle/RememberMeBundle/Security/UserChangingUserProvider.php +++ b/Tests/Functional/Bundle/RememberMeBundle/Security/UserChangingUserProvider.php @@ -21,6 +21,8 @@ class UserChangingUserProvider implements UserProviderInterface { private $inner; + public static $changePassword = false; + public function __construct(InMemoryUserProvider $inner) { $this->inner = $inner; @@ -28,26 +30,31 @@ public function __construct(InMemoryUserProvider $inner) public function loadUserByUsername($username) { - return $this->inner->loadUserByUsername($username); + return $this->changeUser($this->inner->loadUserByUsername($username)); } public function loadUserByIdentifier(string $userIdentifier): UserInterface { - return $this->inner->loadUserByIdentifier($userIdentifier); + return $this->changeUser($this->inner->loadUserByIdentifier($userIdentifier)); } public function refreshUser(UserInterface $user) { - $user = $this->inner->refreshUser($user); - - $alterUser = \Closure::bind(function (InMemoryUser $user) { $user->password = 'foo'; }, null, class_exists(User::class) ? User::class : InMemoryUser::class); - $alterUser($user); - - return $user; + return $this->changeUser($this->inner->refreshUser($user)); } public function supportsClass($class) { return $this->inner->supportsClass($class); } + + private function changeUser(UserInterface $user): UserInterface + { + if (self::$changePassword) { + $alterUser = \Closure::bind(function (InMemoryUser $user) { $user->password = 'changed!'; }, null, class_exists(User::class) ? User::class : InMemoryUser::class); + $alterUser($user); + } + + return $user; + } } diff --git a/Tests/Functional/RememberMeTest.php b/Tests/Functional/RememberMeTest.php index 7af43e11..c1958c7d 100644 --- a/Tests/Functional/RememberMeTest.php +++ b/Tests/Functional/RememberMeTest.php @@ -11,8 +11,15 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\RememberMeBundle\Security\UserChangingUserProvider; + class RememberMeTest extends AbstractWebTestCase { + protected function setUp(): void + { + UserChangingUserProvider::$changePassword = false; + } + /** * @dataProvider provideConfigs */ @@ -51,11 +58,19 @@ public function testUserChangeClearsCookie() $this->assertSame(302, $client->getResponse()->getStatusCode()); $cookieJar = $client->getCookieJar(); - $this->assertNotNull($cookieJar->get('REMEMBERME')); + $this->assertNotNull($cookie = $cookieJar->get('REMEMBERME')); + + UserChangingUserProvider::$changePassword = true; + // change password (through user provider), this deauthenticates the session $client->request('GET', '/profile'); $this->assertRedirect($client->getResponse(), '/login'); $this->assertNull($cookieJar->get('REMEMBERME')); + + // restore the old remember me cookie, it should no longer be valid + $cookieJar->set($cookie); + $client->request('GET', '/profile'); + $this->assertRedirect($client->getResponse(), '/login'); } public function testSessionLessRememberMeLogout() @@ -121,11 +136,19 @@ public function testLegacyUserChangeClearsCookie() $this->assertSame(302, $client->getResponse()->getStatusCode()); $cookieJar = $client->getCookieJar(); - $this->assertNotNull($cookieJar->get('REMEMBERME')); + $this->assertNotNull($cookie = $cookieJar->get('REMEMBERME')); + + UserChangingUserProvider::$changePassword = true; + // change password (through user provider), this deauthenticates the session $client->request('GET', '/profile'); $this->assertRedirect($client->getResponse(), '/login'); $this->assertNull($cookieJar->get('REMEMBERME')); + + // restore the old remember me cookie, it should no longer be valid + $cookieJar->set($cookie); + $client->request('GET', '/profile'); + $this->assertRedirect($client->getResponse(), '/login'); } /** pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy