Using migrate_from with a PasswordEncoderInterface was working fine in Symfony 5.2. It Symfony 5.3, it resulted in an error, because getHasherConfigFromAlgorithm would access it before it is decorated with the adapter.
Full stack-trace:
TypeError:
Argument 1 passed to Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory::createHasher() must be of the type array, object given, called in /var/www/html/vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php on line 157
at vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:73
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->createHasher(object(LegacyPasswordEncoder), true)
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:157)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->getHasherConfigFromAlgorithm(array('algorithm' => 'native', 'cost' => 15, 'hash_algorithm' => 'sha512', 'key_length' => 40, 'ignore_case' => false, 'encode_as_base64' => true, 'iterations' => 5000, 'memory_cost' => null, 'time_cost' => null))
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:77)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->createHasher(array('algorithm' => 'native', 'cost' => 15, 'migrate_from' => array('legacy'), 'hash_algorithm' => 'sha512', 'key_length' => 40, 'ignore_case' => false, 'encode_as_base64' => true, 'iterations' => 5000, 'memory_cost' => null, 'time_cost' => null), true)
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:137)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->getHasherConfigFromAlgorithm(array('algorithm' => 'native', 'cost' => 15, 'migrate_from' => array('legacy'), 'hash_algorithm' => 'sha512', 'key_length' => 40, 'ignore_case' => false, 'encode_as_base64' => true, 'iterations' => 5000, 'memory_cost' => null, 'time_cost' => null))
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:77)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->createHasher(array('algorithm' => 'auto', 'cost' => 15, 'migrate_from' => array('legacy'), 'hash_algorithm' => 'sha512', 'key_length' => 40, 'ignore_case' => false, 'encode_as_base64' => true, 'iterations' => 5000, 'memory_cost' => null, 'time_cost' => null))
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:113)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->createHasherUsingAdapter('App\\Entity\\User')
(vendor/symfony/password-hasher/Hasher/PasswordHasherFactory.php:65)
at Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory->getPasswordHasher(object(User))
(vendor/symfony/security-core/Authentication/Provider/DaoAuthenticationProvider.php:100)
at Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider->checkAuthentication(object(User), object(UsernamePasswordToken))
(vendor/symfony/security-core/Authentication/Provider/UserAuthenticationProvider.php:86)
at Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider->authenticate(object(UsernamePasswordToken))
(vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php:88)
at Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager->authenticate(object(UsernamePasswordToken))
(vendor/symfony/security-http/Firewall/UsernamePasswordFormAuthenticationListener.php:108)
at Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener->attemptAuthentication(object(Request))
(vendor/symfony/security-http/Firewall/AbstractAuthenticationListener.php:136)
at Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener->authenticate(object(RequestEvent))
(vendor/symfony/security-bundle/Debug/WrappedLazyListener.php:49)
at Symfony\Bundle\SecurityBundle\Debug\WrappedLazyListener->authenticate(object(RequestEvent))
(vendor/symfony/security-http/Firewall/AbstractListener.php:26)
at Symfony\Component\Security\Http\Firewall\AbstractListener->__invoke(object(RequestEvent))
(vendor/symfony/security-bundle/Debug/TraceableFirewallListener.php:62)
at Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener->callListeners(object(RequestEvent), object(Generator))
(vendor/symfony/security-http/Firewall.php:86)
at Symfony\Component\Security\Http\Firewall->onKernelRequest(object(RequestEvent), 'kernel.request', object(TraceableEventDispatcher))
(vendor/symfony/event-dispatcher/Debug/WrappedListener.php:117)
at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(RequestEvent), 'kernel.request', object(TraceableEventDispatcher))
(vendor/symfony/event-dispatcher/EventDispatcher.php:230)
at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(RequestEvent))
(vendor/symfony/event-dispatcher/EventDispatcher.php:59)
at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(RequestEvent), 'kernel.request')
(vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:151)
at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(RequestEvent), 'kernel.request')
(vendor/symfony/http-kernel/HttpKernel.php:133)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(vendor/symfony/http-kernel/HttpKernel.php:79)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor/symfony/http-kernel/Kernel.php:199)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(public/index.php:20)
My confguration in security.yml:
encoders:
legacy:
id: 'App\Utils\LegacyPasswordEncoder'
App\Entity\User:
algorithm: auto
cost: 15
migrate_from:
- legacy