@@ -121,12 +121,12 @@ the given password is valid.
121121
122122This functionality is offered by the:class: `Symfony\\ Component\\ Security\\ Core\\ Authentication\\ Provider\\ DaoAuthenticationProvider `.
123123It fetches the user's data from a:class: `Symfony\\ Component\\ Security\\ Core\\ User\\ UserProviderInterface `,
124- uses a:class: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ PasswordEncoderInterface `
124+ uses a:class: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasherInterface `
125125to create a hash of the password and returns an authenticated token if the
126126password was valid::
127127
128+ use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
128129 use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider;
129- use Symfony\Component\Security\Core\Encoder\EncoderFactory;
130130 use Symfony\Component\Security\Core\User\InMemoryUserProvider;
131131 use Symfony\Component\Security\Core\User\UserChecker;
132132
@@ -145,14 +145,14 @@ password was valid::
145145 // for some extra checks: is account enabled, locked, expired, etc.
146146 $userChecker = new UserChecker();
147147
148- // an array of passwordencoders (see below)
149- $encoderFactory = newEncoderFactory (...);
148+ // an array of passwordhashers (see below)
149+ $hasherFactory = newPasswordHasherFactoryInterface (...);
150150
151151 $daoProvider = new DaoAuthenticationProvider(
152152 $userProvider,
153153 $userChecker,
154154 'secured_area',
155- $encoderFactory
155+ $hasherFactory
156156 );
157157
158158 $daoProvider->authenticate($unauthenticatedToken);
@@ -165,96 +165,105 @@ password was valid::
165165 It is also possible to let multiple user providers try to find the user's
166166 data, using the:class: `Symfony\\ Component\\ Security\\ Core\\ User\\ ChainUserProvider `.
167167
168- The Password Encoder Factory
169- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168+ .. _the-password-encoder-factory :
169+
170+ The Password Hasher Factory
171+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
170172
171173The:class: `Symfony\\ Component\\ Security\\ Core\\ Authentication\\ Provider\\ DaoAuthenticationProvider `
172- usesan encoder factory to create a passwordencoder for a given type of
173- user. This allows you to use differentencoding strategies for different
174- types of users. The default:class: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ EncoderFactory `
175- receives an array ofencoders ::
174+ usesa factory to create a passwordhasher for a given type of user. This allows
175+ you to use differenthashing strategies for different types of users.
176+ The default:class: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ PasswordHasherFactory `
177+ receives an array ofhashers ::
176178
177179 use Acme\Entity\LegacyUser;
178- use Symfony\Component\Security\Core\Encoder\EncoderFactory ;
179- use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder ;
180+ use Symfony\Component\PasswordHasher\Hasher\MessageDigestPasswordHasher ;
181+ use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory ;
180182 use Symfony\Component\Security\Core\User\InMemoryUser;
181183
182- $defaultEncoder = newMessageDigestPasswordEncoder ('sha512', true, 5000);
183- $weakEncoder = newMessageDigestPasswordEncoder ('md5', true, 1);
184+ $defaultHasher = newMessageDigestPasswordHasher ('sha512', true, 5000);
185+ $weakHasher = newMessageDigestPasswordHasher ('md5', true, 1);
184186
185- $encoders = [
186- InMemoryUser::class => $defaultEncoder ,
187- LegacyUser::class => $weakEncoder ,
187+ $hashers = [
188+ InMemoryUser::class => $defaultHasher ,
189+ LegacyUser::class => $weakHasher ,
188190 // ...
189191 ];
190- $encoderFactory = newEncoderFactory($encoders );
192+ $hasherFactory = newPasswordHasherFactory($hashers );
191193
192- Eachencoder should implement:class: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ PasswordEncoderInterface `
194+ Eachhasher should implement:class: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasherInterface `
193195or be an array with a ``class `` and an ``arguments `` key, which allows the
194- encoder factory to construct the encoder only when it is needed.
196+ hasher factory to construct the hasher only when it is needed.
197+
198+ .. _creating-a-custom-password-encoder :
195199
196- Creating a custom PasswordEncoder
197- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200+ Creating a custom PasswordHasher
201+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
198202
199- There are many built-in passwordencoders . But if you need to create your
203+ There are many built-in passwordhasher . But if you need to create your
200204own, it needs to follow these rules:
201205
202- #. The class must implement:class: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ PasswordEncoderInterface `
203- (you can also extend:class: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ BasePasswordEncoder `);
206+ #. The class must implement:class: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasherInterface `
207+ (you can also extend:class: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasher `);
204208
205209#. The implementations of
206- :method: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ PasswordEncoderInterface::encodePassword `
210+ :method: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasherInterface::hashPassword `
207211 and
208- :method: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ PasswordEncoderInterface ::isPasswordValid `
212+ :method: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ UserPasswordHasherInterface ::isPasswordValid `
209213 must first of all make sure the password is not too long, i.e. the password length is no longer
210214 than 4096 characters. This is for security reasons (see `CVE-2013-5750 `_), and you can use the
211- :method: `Symfony\\ Component\\ Security \\ Core \\ Encoder \\ BasePasswordEncoder ::isPasswordTooLong `
215+ :method: `Symfony\\ Component\\ PasswordHasher \\ Hasher \\ CheckPasswordLengthTrait ::isPasswordTooLong `
212216 method for this check::
213217
214- use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
218+ use Symfony\Component\PasswordHasher\Hasher\CheckPasswordLengthTrait;
219+ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
215220 use Symfony\Component\Security\Core\Exception\BadCredentialsException;
216221
217- classFoobarEncoder extendsBasePasswordEncoder
222+ classFoobarHasher extendsUserPasswordHasher
218223 {
219- public function encodePassword($raw, $salt)
224+ use CheckPasswordLengthTrait;
225+
226+ public function hashPassword(UserInterface $user, string $plainPassword): string
220227 {
221- if ($this->isPasswordTooLong($raw )) {
228+ if ($this->isPasswordTooLong($user->getPassword() )) {
222229 throw new BadCredentialsException('Invalid password.');
223230 }
224231
225232 // ...
226233 }
227234
228- public function isPasswordValid($encoded, $raw, $salt )
235+ public function isPasswordValid(UserInterface $user, string $plainPassword )
229236 {
230- if ($this->isPasswordTooLong($raw )) {
237+ if ($this->isPasswordTooLong($user->getPassword() )) {
231238 return false;
232239 }
233240
234241 // ...
235242 }
236243 }
237244
238- Using Password Encoders
239- ~~~~~~~~~~~~~~~~~~~~~~~
245+ .. _using-password-encoders :
240246
241- When the:method: `Symfony\\ Component\\ Security\\ Core\\ Encoder\\ EncoderFactory::getEncoder `
242- method of the password encoder factory is called with the user object as
243- its first argument, it will return an encoder of type:class: `Symfony\\ Component\\ Security\\ Core\\ Encoder\\ PasswordEncoderInterface `
244- which should be used to encode this user's password::
247+ Using Password Hashers
248+ ~~~~~~~~~~~~~~~~~~~~~~
249+
250+ When the:method: `Symfony\\ Component\\ PasswordHasher\\ Hasher\\ PasswordHasherFactory::getPasswordHasher `
251+ method of the password hasher factory is called with the user object as
252+ its first argument, it will return a hasher of type:class: `Symfony\\ Component\\ PasswordHasher\\ PasswordHasherInterface `
253+ which should be used to hash this user's password::
245254
246255 // a Acme\Entity\LegacyUser instance
247256 $user = ...;
248257
249258 // the password that was submitted, e.g. when registering
250259 $plainPassword = ...;
251260
252- $encoder = $encoderFactory->getEncoder ($user);
261+ $hasher = $hasherFactory->getPasswordHasher ($user);
253262
254- // returns $weakEncoder (see above)
255- $encodedPassword = $encoder->encodePassword($plainPassword , $user->getSalt() );
263+ // returns $weakHasher (see above)
264+ $hashedPassword = $hasher->hashPassword($user , $plainPassword );
256265
257- $user->setPassword($encodedPassword );
266+ $user->setPassword($hashedPassword );
258267
259268 // ... save the user
260269
@@ -267,11 +276,7 @@ in) is correct, you can use::
267276 // the submitted password, e.g. from the login form
268277 $plainPassword = ...;
269278
270- $validPassword = $encoder->isPasswordValid(
271- $user->getPassword(), // the encoded password
272- $plainPassword, // the submitted password
273- $user->getSalt()
274- );
279+ $validPassword = $hasher->isPasswordValid($user, $plainPassword);
275280
276281Authentication Events
277282---------------------