Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e197398

Browse files
[Security] deprecate BCryptPasswordEncoder in favor of NativePasswordEncoder
1 parent 89ec311 commit e197398

File tree

18 files changed

+151
-46
lines changed

18 files changed

+151
-46
lines changed

UPGRADE-4.3.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,14 @@ Security
168168
```
169169

170170
* The `Argon2iPasswordEncoder` class has been deprecated, use `SodiumPasswordEncoder` instead.
171+
* The `BCryptPasswordEncoder` class has been deprecated, use `NativePasswordEncoder` instead.
171172
* Not implementing the methods `__serialize` and `__unserialize` in classes implementing
172173
the `TokenInterface` is deprecated
173174

174175
SecurityBundle
175176
--------------
176177

177-
* Configuring encoders using `argon2i` as algorithm has been deprecated, use `auto` instead.
178+
* Configuring encoders using `argon2i` or `bcrypt` as algorithm has been deprecated, use `auto` instead.
178179

179180
TwigBridge
180181
----------

UPGRADE-5.0.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ Security
342342
```
343343

344344
* The `Argon2iPasswordEncoder` class has been removed, use `SodiumPasswordEncoder` instead.
345+
* The `BCryptPasswordEncoder` class has been removed, use `NativePasswordEncoder` instead.
345346
* Classes implementing the `TokenInterface` must implement the two new methods
346347
`__serialize` and `__unserialize`
347348

@@ -364,7 +365,7 @@ SecurityBundle
364365
changed to underscores.
365366
Before: `my-cookie` deleted the `my_cookie` cookie (with an underscore).
366367
After: `my-cookie` deletes the `my-cookie` cookie (with a dash).
367-
* Configuring encoders using `argon2i` as algorithm is not supported anymore, use `sodium` instead.
368+
* Configuring encoders using `argon2i` or `bcrypt` as algorithm is not supported anymore, use `auto` instead.
368369

369370
Serializer
370371
----------

src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected function configure()
7070
security:
7171
encoders:
7272
Symfony\Component\Security\Core\User\User: plaintext
73-
App\Entity\User: bcrypt
73+
App\Entity\User: auto
7474
</comment>
7575
7676
If you execute the command non-interactively, the first available configured

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ private function createEncoder($config, ContainerBuilder $container)
558558

559559
// bcrypt encoder
560560
if ('bcrypt' === $config['algorithm']) {
561+
@trigger_error('Configuring an encoder with "bcrypt" as algorithm is deprecated since Symfony 4.3, use "auto" instead.', E_USER_DEPRECATED);
562+
561563
return [
562564
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
563565
'arguments' => [$config['cost'] ?? 13],

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,10 @@ public function testEncoders()
306306
'arguments' => ['sha1', false, 5, 30],
307307
],
308308
'JMS\FooBundle\Entity\User6' => [
309-
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
310-
'arguments' => [15],
311-
],
312-
'JMS\FooBundle\Entity\User7' => [
313309
'class' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder',
314310
'arguments' => [8, 102400, 15],
315311
],
316-
'JMS\FooBundle\Entity\User8' => [
312+
'JMS\FooBundle\Entity\User7' => [
317313
'algorithm' => 'auto',
318314
'hash_algorithm' => 'sha512',
319315
'key_length' => 40,
@@ -371,25 +367,13 @@ public function testEncodersWithLibsodium()
371367
'arguments' => ['sha1', false, 5, 30],
372368
],
373369
'JMS\FooBundle\Entity\User6' => [
374-
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
375-
'arguments' => [15],
370+
'class' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder',
371+
'arguments' => [8, 102400, 15],
376372
],
377373
'JMS\FooBundle\Entity\User7' => [
378374
'class' => 'Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder',
379375
'arguments' => [8, 128 * 1024 * 1024],
380376
],
381-
'JMS\FooBundle\Entity\User8' => [
382-
'algorithm' => 'auto',
383-
'hash_algorithm' => 'sha512',
384-
'key_length' => 40,
385-
'ignore_case' => false,
386-
'encode_as_base64' => true,
387-
'iterations' => 5000,
388-
'cost' => null,
389-
'memory_cost' => null,
390-
'time_cost' => null,
391-
'threads' => null,
392-
],
393377
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
394378
}
395379

@@ -441,15 +425,42 @@ public function testEncodersWithArgon2i()
441425
'arguments' => ['sha1', false, 5, 30],
442426
],
443427
'JMS\FooBundle\Entity\User6' => [
444-
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
445-
'arguments' => [15],
428+
'class' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder',
429+
'arguments' => [8, 102400, 15],
446430
],
447431
'JMS\FooBundle\Entity\User7' => [
448432
'class' => 'Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder',
449433
'arguments' => [256, 1, 2],
450434
],
451-
'JMS\FooBundle\Entity\User8' => [
452-
'algorithm' => 'auto',
435+
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
436+
}
437+
438+
/**
439+
* @group legacy
440+
*/
441+
public function testEncodersWithBCrypt()
442+
{
443+
$container = $this->getContainer('bcrypt_encoder');
444+
445+
$this->assertEquals([[
446+
'JMS\FooBundle\Entity\User1' => [
447+
'class' => 'Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder',
448+
'arguments' => [false],
449+
],
450+
'JMS\FooBundle\Entity\User2' => [
451+
'algorithm' => 'sha1',
452+
'encode_as_base64' => false,
453+
'iterations' => 5,
454+
'hash_algorithm' => 'sha512',
455+
'key_length' => 40,
456+
'ignore_case' => false,
457+
'cost' => null,
458+
'memory_cost' => null,
459+
'time_cost' => null,
460+
'threads' => null,
461+
],
462+
'JMS\FooBundle\Entity\User3' => [
463+
'algorithm' => 'md5',
453464
'hash_algorithm' => 'sha512',
454465
'key_length' => 40,
455466
'ignore_case' => false,
@@ -460,6 +471,19 @@ public function testEncodersWithArgon2i()
460471
'time_cost' => null,
461472
'threads' => null,
462473
],
474+
'JMS\FooBundle\Entity\User4' => new Reference('security.encoder.foo'),
475+
'JMS\FooBundle\Entity\User5' => [
476+
'class' => 'Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder',
477+
'arguments' => ['sha1', false, 5, 30],
478+
],
479+
'JMS\FooBundle\Entity\User6' => [
480+
'class' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder',
481+
'arguments' => [8, 102400, 15],
482+
],
483+
'JMS\FooBundle\Entity\User7' => [
484+
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
485+
'arguments' => [15],
486+
],
463487
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
464488
}
465489

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
$this->load('container1.php', $container);
4+
5+
$container->loadFromExtension('security', [
6+
'encoders' => [
7+
'JMS\FooBundle\Entity\User7' => [
8+
'algorithm' => 'bcrypt',
9+
'cost' => 15,
10+
],
11+
],
12+
]);

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,12 @@
2222
'key_length' => 30,
2323
],
2424
'JMS\FooBundle\Entity\User6' => [
25-
'algorithm' => 'bcrypt',
26-
'cost' => 15,
27-
],
28-
'JMS\FooBundle\Entity\User7' => [
2925
'algorithm' => 'native',
3026
'time_cost' => 8,
3127
'memory_cost' => 100,
3228
'cost' => 15,
3329
],
34-
'JMS\FooBundle\Entity\User8' => [
30+
'JMS\FooBundle\Entity\User7' => [
3531
'algorithm' => 'auto',
3632
],
3733
],
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:sec="http://symfony.com/schema/dic/security"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
7+
8+
<imports>
9+
<import resource="container1.xml"/>
10+
</imports>
11+
12+
<sec:config>
13+
<sec:encoder class="JMS\FooBundle\Entity\User7" algorithm="bcrypt" cost="15" />
14+
</sec:config>
15+
16+
</container>

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616

1717
<encoder class="JMS\FooBundle\Entity\User5" algorithm="pbkdf2" hash-algorithm="sha1" encode-as-base64="false" iterations="5" key-length="30" />
1818

19-
<encoder class="JMS\FooBundle\Entity\User6" algorithm="bcrypt" cost="15" />
19+
<encoder class="JMS\FooBundle\Entity\User6" algorithm="native" time-cost="8" memory-cost="100" cost="15" />
2020

21-
<encoder class="JMS\FooBundle\Entity\User7" algorithm="native" time-cost="8" memory-cost="100" cost="15" />
22-
23-
<encoder class="JMS\FooBundle\Entity\User8" algorithm="auto" />
21+
<encoder class="JMS\FooBundle\Entity\User7" algorithm="auto" />
2422

2523
<provider name="default">
2624
<memory>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
imports:
2+
- { resource: container1.yml }
3+
4+
security:
5+
encoders:
6+
JMS\FooBundle\Entity\User7:
7+
algorithm: bcrypt
8+
cost: 15

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ security:
1616
iterations: 5
1717
key_length: 30
1818
JMS\FooBundle\Entity\User6:
19-
algorithm: bcrypt
20-
cost: 15
21-
JMS\FooBundle\Entity\User7:
2219
algorithm: native
2320
time_cost: 8
2421
memory_cost: 100
2522
cost: 15
26-
JMS\FooBundle\Entity\User8:
23+
JMS\FooBundle\Entity\User7:
2724
algorithm: auto
2825

2926
providers:

src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder;
1919
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
2020
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
21+
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
2122
use Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder;
2223
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
2324

@@ -54,8 +55,12 @@ public function testEncodeNoPasswordNoInteraction()
5455
$this->assertEquals($statusCode, 1);
5556
}
5657

58+
/**
59+
* @group legacy
60+
*/
5761
public function testEncodePasswordBcrypt()
5862
{
63+
$this->setupBcrypt();
5964
$this->passwordEncoderCommandTester->execute([
6065
'command' => 'security:encode-password',
6166
'password' => 'password',
@@ -95,6 +100,23 @@ public function testEncodePasswordArgon2i()
95100
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
96101
}
97102

103+
public function testEncodePasswordNative()
104+
{
105+
$this->passwordEncoderCommandTester->execute([
106+
'command' => 'security:encode-password',
107+
'password' => 'password',
108+
'user-class' => 'Custom\Class\Native\User',
109+
], ['interactive' => false]);
110+
111+
$output = $this->passwordEncoderCommandTester->getDisplay();
112+
$this->assertContains('Password encoding succeeded', $output);
113+
114+
$encoder = new NativePasswordEncoder();
115+
preg_match('# Encoded password\s{1,}([\w+\/$.,=]+={0,2})\s+#', $output, $matches);
116+
$hash = $matches[1];
117+
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
118+
}
119+
98120
public function testEncodePasswordSodium()
99121
{
100122
if (!SodiumPasswordEncoder::isSupported()) {
@@ -162,12 +184,12 @@ public function testEncodePasswordEmptySaltOutput()
162184
$this->assertNotContains(' Generated salt ', $this->passwordEncoderCommandTester->getDisplay());
163185
}
164186

165-
public function testEncodePasswordBcryptOutput()
187+
public function testEncodePasswordNativeOutput()
166188
{
167189
$this->passwordEncoderCommandTester->execute([
168190
'command' => 'security:encode-password',
169191
'password' => 'p@ssw0rd',
170-
'user-class' => 'Custom\Class\Bcrypt\User',
192+
'user-class' => 'Custom\Class\Native\User',
171193
], ['interactive' => false]);
172194

173195
$this->assertNotContains(' Generated salt ', $this->passwordEncoderCommandTester->getDisplay());
@@ -233,8 +255,8 @@ public function testEncodePasswordAsksNonProvidedUserClass()
233255
], ['decorated' => false]);
234256

235257
$this->assertContains(<<<EOTXT
236-
For which user class would you like to encode a password? [Custom\Class\Bcrypt\User]:
237-
[0] Custom\Class\Bcrypt\User
258+
For which user class would you like to encode a password? [Custom\Class\Native\User]:
259+
[0] Custom\Class\Native\User
238260
[1] Custom\Class\Pbkdf2\User
239261
[2] Custom\Class\Test\User
240262
[3] Symfony\Component\Security\Core\User\User
@@ -301,6 +323,19 @@ private function setupArgon2i()
301323
$this->passwordEncoderCommandTester = new CommandTester($passwordEncoderCommand);
302324
}
303325

326+
private function setupBcrypt()
327+
{
328+
putenv('COLUMNS='.(119 + \strlen(PHP_EOL)));
329+
$kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'bcrypt.yml']);
330+
$kernel->boot();
331+
332+
$application = new Application($kernel);
333+
334+
$passwordEncoderCommand = $application->get('security:encode-password');
335+
336+
$this->passwordEncoderCommandTester = new CommandTester($passwordEncoderCommand);
337+
}
338+
304339
private function setupSodium()
305340
{
306341
putenv('COLUMNS='.(119 + \strlen(PHP_EOL)));
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
imports:
2+
- { resource: config.yml }
3+
4+
security:
5+
encoders:
6+
Custom\Class\Bcrypt\User:
7+
algorithm: bcrypt

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/PasswordEncode/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ imports:
44
security:
55
encoders:
66
Symfony\Component\Security\Core\User\User: plaintext
7-
Custom\Class\Bcrypt\User:
8-
algorithm: bcrypt
7+
Custom\Class\Native\User:
8+
algorithm: native
99
cost: 10
1010
Custom\Class\Pbkdf2\User:
1111
algorithm: pbkdf2

src/Symfony/Component/Security/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ CHANGELOG
2121
* Dispatch `AuthenticationFailureEvent` on `security.authentication.failure`
2222
* Dispatch `InteractiveLoginEvent` on `security.interactive_login`
2323
* Dispatch `SwitchUserEvent` on `security.switch_user`
24-
* Deprecated `Argon2iPasswordEncoder`, use `SodiumPasswordEncoder`
24+
* Deprecated `Argon2iPasswordEncoder`, use `SodiumPasswordEncoder` instead
25+
* Deprecated `BCryptPasswordEncoder`, use `NativePasswordEncoder` instead
2526

2627
4.2.0
2728
-----

src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111

1212
namespace Symfony\Component\Security\Core\Encoder;
1313

14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', BCryptPasswordEncoder::class, NativePasswordEncoder::class), E_USER_DEPRECATED);
15+
1416
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1517

1618
/**
1719
* @author Elnur Abdurrakhimov <[email protected]>
1820
* @author Terje Bråten <[email protected]>
21+
*
22+
* @deprecated since Symfony 4.3, use NativePasswordEncoder instead
1923
*/
2024
class BCryptPasswordEncoder extends BasePasswordEncoder implements SelfSaltingEncoderInterface
2125
{

src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ private function getEncoderConfigFromAlgorithm($config)
106106
],
107107
];
108108

109+
/* @deprecated since Symfony 4.3 */
109110
case 'bcrypt':
110111
return [
111112
'class' => BCryptPasswordEncoder::class,

0 commit comments

Comments
 (0)