@@ -665,7 +665,7 @@ see :doc:`/cookbook/security/form_login`.
665665 ),
666666 ),
667667
668- **3. Be sure`` /login_check`` is behind a firewall **
668+ **3. Be sure /login_check is behind a firewall **
669669
670670 Next, make sure that your ``check_path `` URL (e.g. ``/login_check ``)
671671 is behind the firewall you're using for your form login (in this example,
@@ -1221,7 +1221,7 @@ in plain text (whether those users are stored in a configuration file or in
12211221a database somewhere). Of course, in a real application, you'll want to encode
12221222your users' passwords for security reasons. This is easily accomplished by
12231223mapping your User class to one of several built-in "encoders". For example,
1224- to store your users in memory, but obscure their passwords via ``sha1 ``,
1224+ to store your users in memory, but obscure their passwords via ``bcrypt ``,
12251225do the following:
12261226
12271227..configuration-block ::
@@ -1235,14 +1235,17 @@ do the following:
12351235in_memory :
12361236memory :
12371237users :
1238- ryan :{ password: bb87a29949f3a1ee0559f8a57357487151281386, roles: 'ROLE_USER' }
1239- admin :{ password: 74913f5cd5f61ec0bcfdb775414c2fb3d161b620, roles: 'ROLE_ADMIN' }
1238+ ryan :
1239+ password :$2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO
1240+ roles :' ROLE_USER'
1241+ admin :
1242+ password :$2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW
1243+ roles :' ROLE_ADMIN'
12401244
12411245encoders :
12421246Symfony\Component\Security\Core\User\User :
1243- algorithm :sha1
1244- iterations :1
1245- encode_as_base64 :false
1247+ algorithm :bcrypt
1248+ cost :12
12461249
12471250 ..code-block ::xml
12481251
@@ -1252,18 +1255,18 @@ do the following:
12521255 <provider name =" in_memory" >
12531256 <memory >
12541257 <user name =" ryan"
1255- password =" bb87a29949f3a1ee0559f8a57357487151281386 "
1258+ password =" $2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO "
12561259roles =" ROLE_USER" />
12571260 <user name =" admin"
1258- password =" 74913f5cd5f61ec0bcfdb775414c2fb3d161b620 "
1261+ password =" $2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW "
12591262roles =" ROLE_ADMIN" />
12601263 </memory >
12611264 </provider >
12621265
12631266 <encoder class =" Symfony\Component\Security\Core\User\User"
1264- algorithm =" sha1 "
1265- iterations = " 1 "
1266- encode_as_base64 = " false " />
1267+ algorithm =" bcrypt "
1268+ cost = " 12 "
1269+ />
12671270 </config >
12681271
12691272 ..code-block ::php
@@ -1276,11 +1279,11 @@ do the following:
12761279 'memory' => array(
12771280 'users' => array(
12781281 'ryan' => array(
1279- 'password' => 'bb87a29949f3a1ee0559f8a57357487151281386 ',
1282+ 'password' => '$2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO ',
12801283 'roles' => 'ROLE_USER',
12811284 ),
12821285 'admin' => array(
1283- 'password' => '74913f5cd5f61ec0bcfdb775414c2fb3d161b620 ',
1286+ 'password' => '$2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW ',
12841287 'roles' => 'ROLE_ADMIN',
12851288 ),
12861289 ),
@@ -1289,77 +1292,36 @@ do the following:
12891292 ),
12901293 'encoders' => array(
12911294 'Symfony\Component\Security\Core\User\User' => array(
1292- 'algorithm' => 'sha1',
1293- 'iterations' => 1,
1294- 'encode_as_base64' => false,
1295+ 'algorithm' => 'bcrypt',
1296+ 'iterations' => 12,
12951297 ),
12961298 ),
12971299 ));
12981300
1299- By setting the ``iterations `` to ``1 `` and the ``encode_as_base64 `` to false,
1300- the password is simply run through the ``sha1 `` algorithm one time and without
1301- any extra encoding. You can now calculate the hashed password either programmatically
1302- (e.g. ``hash('sha1', 'ryanpass') ``) or via some online tool like `functions-online.com `_
1303-
1304- ..tip ::
1305-
1306- Supported algorithms for this method depend on your PHP version.
1307- A full list is available calling the PHP function:phpfunction: `hash_algos `.
1308-
1309- If you're creating your users dynamically (and storing them in a database),
1310- you can use even tougher hashing algorithms and then rely on an actual password
1311- encoder object to help you encode passwords. For example, suppose your User
1312- object is ``Acme\UserBundle\Entity\User `` (like in the above example). First,
1313- configure the encoder for that user:
1314-
1315- ..configuration-block ::
1316-
1317- ..code-block ::yaml
1318-
1319- # app/config/security.yml
1320- security :
1321- # ...
1322-
1323- encoders :
1324- Acme\UserBundle\Entity\User :sha512
1325-
1326- ..code-block ::xml
1301+ ..versionadded ::2.2
1302+ The BCrypt encoder was introduced in Symfony 2.2.
13271303
1328- <!-- app/config/security.xml -->
1329- < config >
1330- <!-- ... -->
1304+ You can now calculate the hashed password either programmatically
1305+ (e.g. `` password_hash('ryanpass', PASSWORD_BCRYPT, array('cost' => 12)); ``)
1306+ or via some online tool.
13311307
1332- <encoder class =" Acme\UserBundle\Entity\User" algorithm =" sha512" />
1333- </config >
1308+ ..include ::/cookbook/security/_ircmaxwell_password-compat.rst.inc
13341309
1335- ..code-block ::php
1336-
1337- // app/config/security.php
1338- $container->loadFromExtension('security', array(
1339- // ...
1340- 'encoders' => array(
1341- 'Acme\UserBundle\Entity\User' => 'sha512',
1342- ),
1343- ));
1344-
1345- In this case, you're using the stronger ``sha512 `` algorithm. Also, since
1346- you've simply specified the algorithm (``sha512 ``) as a string, the system
1347- will default to hashing your password 5000 times in a row and then encoding
1348- it as base64. In other words, the password has been greatly obfuscated so
1349- that the hashed password can't be decoded (i.e. you can't determine the password
1350- from the hashed password).
1310+ Supported algorithms for this method depend on your PHP version. A full list
1311+ is available by calling the PHP function:phpfunction: `hash_algos `.
13511312
13521313..versionadded ::2.2
13531314 As of Symfony 2.2 you can also use the:ref: `PBKDF2 <reference-security-pbkdf2 >`
1354- and :ref: ` BCrypt < reference-security-bcrypt >` passwordencoders .
1315+ passwordencoder .
13551316
13561317Determining the Hashed Password
13571318...............................
13581319
1359- If you have some sort of registration form for users, you'll need to be able
1360- to determine the hashed password so that you can set it on your user. No
1361- matter what algorithm you configure for your user object, the hashed password
1362- can always be determined in the following way from a controller::
1320+ If you're storing users in the database and you have some sort of registration
1321+ form for users, you'll need to be able to determine the hashed password so
1322+ that you can set it on your user before inserting it. No matter what algorithm
1323+ you configure for your user object, the hashed password can always be determined
1324+ in the following way from a controller::
13631325
13641326 $factory = $this->get('security.encoder_factory');
13651327 $user = new Acme\UserBundle\Entity\User();
@@ -1368,6 +1330,10 @@ can always be determined in the following way from a controller::
13681330 $password = $encoder->encodePassword('ryanpass', $user->getSalt());
13691331 $user->setPassword($password);
13701332
1333+ In order for this to work, just make sure that you have the encoder for your
1334+ user class (e.g. ``Acme\UserBundle\Entity\User ``) configured under the ``encoders ``
1335+ key in ``app/config/security.yml ``.
1336+
13711337..caution ::
13721338
13731339 When you allow a user to submit a plaintext password (e.g. registration
@@ -1956,5 +1922,4 @@ Learn more from the Cookbook
19561922.. _`JMSSecurityExtraBundle` :http://jmsyst.com/bundles/JMSSecurityExtraBundle/1.2
19571923.. _`FOSUserBundle` :https://github.com/FriendsOfSymfony/FOSUserBundle
19581924.. _`implement the\S erializable interface` :http://php.net/manual/en/class.serializable.php
1959- .. _`functions-online.com` :http://www.functions-online.com/sha1.html
19601925.. _`Timing attack` :http://en.wikipedia.org/wiki/Timing_attack