@@ -660,7 +660,7 @@ see :doc:`/cookbook/security/form_login`.
660660 ),
661661 ),
662662
663- **3. Be sure`` /login_check`` is behind a firewall **
663+ **3. Be sure /login_check is behind a firewall **
664664
665665 Next, make sure that your ``check_path `` URL (e.g. ``/login_check ``)
666666 is behind the firewall you're using for your form login (in this example,
@@ -1206,19 +1206,6 @@ custom user class is that it implements the :class:`Symfony\\Component\\Security
12061206interface. This means that your concept of a "user" can be anything, as long
12071207as it implements this interface.
12081208
1209- ..versionadded ::2.1
1210- In Symfony 2.1, the ``equals `` method was removed from ``UserInterface ``.
1211- If you need to override the default implementation of comparison logic,
1212- implement the new:class: `Symfony\\ Component\\ Security\\ Core\\ User\\ EquatableInterface `
1213- interface.
1214-
1215- ..note ::
1216-
1217- The user object will be serialized and saved in the session during requests,
1218- therefore it is recommended that you `implement the\S erializable interface `_
1219- in your user object. This is especially important if your ``User `` class
1220- has a parent class with private properties.
1221-
12221209Next, configure an ``entity `` user provider, and point it to your ``User ``
12231210class:
12241211
@@ -1278,7 +1265,7 @@ in plain text (whether those users are stored in a configuration file or in
12781265a database somewhere). Of course, in a real application, you'll want to encode
12791266your users' passwords for security reasons. This is easily accomplished by
12801267mapping your User class to one of several built-in "encoders". For example,
1281- to store your users in memory, but obscure their passwords via ``sha1 ``,
1268+ to store your users in memory, but obscure their passwords via ``bcrypt ``,
12821269do the following:
12831270
12841271..configuration-block ::
@@ -1292,14 +1279,17 @@ do the following:
12921279in_memory :
12931280memory :
12941281users :
1295- ryan :{ password: bb87a29949f3a1ee0559f8a57357487151281386, roles: 'ROLE_USER' }
1296- admin :{ password: 74913f5cd5f61ec0bcfdb775414c2fb3d161b620, roles: 'ROLE_ADMIN' }
1282+ ryan :
1283+ password :$2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO
1284+ roles :' ROLE_USER'
1285+ admin :
1286+ password :$2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW
1287+ roles :' ROLE_ADMIN'
12971288
12981289encoders :
12991290Symfony\Component\Security\Core\User\User :
1300- algorithm :sha1
1301- iterations :1
1302- encode_as_base64 :false
1291+ algorithm :bcrypt
1292+ cost :12
13031293
13041294 ..code-block ::xml
13051295
@@ -1309,18 +1299,18 @@ do the following:
13091299 <provider name =" in_memory" >
13101300 <memory >
13111301 <user name =" ryan"
1312- password =" bb87a29949f3a1ee0559f8a57357487151281386 "
1302+ password =" $2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO "
13131303roles =" ROLE_USER" />
13141304 <user name =" admin"
1315- password =" 74913f5cd5f61ec0bcfdb775414c2fb3d161b620 "
1305+ password =" $2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW "
13161306roles =" ROLE_ADMIN" />
13171307 </memory >
13181308 </provider >
13191309
13201310 <encoder class =" Symfony\Component\Security\Core\User\User"
1321- algorithm =" sha1 "
1322- iterations = " 1 "
1323- encode_as_base64 = " false " />
1311+ algorithm =" bcrypt "
1312+ cost = " 12 "
1313+ />
13241314 </config >
13251315
13261316 ..code-block ::php
@@ -1333,11 +1323,11 @@ do the following:
13331323 'memory' => array(
13341324 'users' => array(
13351325 'ryan' => array(
1336- 'password' => 'bb87a29949f3a1ee0559f8a57357487151281386 ',
1326+ 'password' => '$2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO ',
13371327 'roles' => 'ROLE_USER',
13381328 ),
13391329 'admin' => array(
1340- 'password' => '74913f5cd5f61ec0bcfdb775414c2fb3d161b620 ',
1330+ 'password' => '$2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW ',
13411331 'roles' => 'ROLE_ADMIN',
13421332 ),
13431333 ),
@@ -1346,77 +1336,36 @@ do the following:
13461336 ),
13471337 'encoders' => array(
13481338 'Symfony\Component\Security\Core\User\User' => array(
1349- 'algorithm' => 'sha1',
1350- 'iterations' => 1,
1351- 'encode_as_base64' => false,
1339+ 'algorithm' => 'bcrypt',
1340+ 'iterations' => 12,
13521341 ),
13531342 ),
13541343 ));
13551344
1356- By setting the ``iterations `` to ``1 `` and the ``encode_as_base64 `` to false,
1357- the password is simply run through the ``sha1 `` algorithm one time and without
1358- any extra encoding. You can now calculate the hashed password either programmatically
1359- (e.g. ``hash('sha1', 'ryanpass') ``) or via some online tool like `functions-online.com `_
1360-
1361- ..tip ::
1362-
1363- Supported algorithms for this method depend on your PHP version.
1364- A full list is available calling the PHP function:phpfunction: `hash_algos `.
1365-
1366- If you're creating your users dynamically (and storing them in a database),
1367- you can use even tougher hashing algorithms and then rely on an actual password
1368- encoder object to help you encode passwords. For example, suppose your User
1369- object is ``Acme\UserBundle\Entity\User `` (like in the above example). First,
1370- configure the encoder for that user:
1371-
1372- ..configuration-block ::
1373-
1374- ..code-block ::yaml
1375-
1376- # app/config/security.yml
1377- security :
1378- # ...
1379-
1380- encoders :
1381- Acme\UserBundle\Entity\User :sha512
1382-
1383- ..code-block ::xml
1384-
1385- <!-- app/config/security.xml-->
1386- <config >
1387- <!-- ...-->
1388-
1389- <encoder class =" Acme\UserBundle\Entity\User" algorithm =" sha512" />
1390- </config >
1345+ ..versionadded ::2.2
1346+ The BCrypt encoder was introduced in Symfony 2.2.
13911347
1392- ..code-block ::php
1348+ You can now calculate the hashed password either programmatically
1349+ (e.g. ``password_hash('ryanpass', PASSWORD_BCRYPT, array('cost' => 12)); ``)
1350+ or via some online tool.
13931351
1394- // app/config/security.php
1395- $container->loadFromExtension('security', array(
1396- // ...
1397- 'encoders' => array(
1398- 'Acme\UserBundle\Entity\User' => 'sha512',
1399- ),
1400- ));
1352+ ..include ::/cookbook/security/_ircmaxwell_password-compat.rst.inc
14011353
1402- In this case, you're using the stronger ``sha512 `` algorithm. Also, since
1403- you've simply specified the algorithm (``sha512 ``) as a string, the system
1404- will default to hashing your password 5000 times in a row and then encoding
1405- it as base64. In other words, the password has been greatly obfuscated so
1406- that the hashed password can't be decoded (i.e. you can't determine the password
1407- from the hashed password).
1354+ Supported algorithms for this method depend on your PHP version. A full list
1355+ is available by calling the PHP function:phpfunction: `hash_algos `.
14081356
14091357..versionadded ::2.2
14101358 As of Symfony 2.2 you can also use the:ref: `PBKDF2 <reference-security-pbkdf2 >`
1411- and :ref: ` BCrypt < reference-security-bcrypt >` passwordencoders .
1359+ passwordencoder .
14121360
14131361Determining the Hashed Password
14141362...............................
14151363
1416- If you have some sort of registration form for users, you'll need to be able
1417- to determine the hashed password so that you can set it on your user. No
1418- matter what algorithm you configure for your user object, the hashed password
1419- can always be determined in the following way from a controller::
1364+ If you're storing users in the database and you have some sort of registration
1365+ form for users, you'll need to be able to determine the hashed password so
1366+ that you can set it on your user before inserting it. No matter what algorithm
1367+ you configure for your user object, the hashed password can always be determined
1368+ in the following way from a controller::
14201369
14211370 $factory = $this->get('security.encoder_factory');
14221371 $user = new Acme\UserBundle\Entity\User();
@@ -1425,6 +1374,10 @@ can always be determined in the following way from a controller::
14251374 $password = $encoder->encodePassword('ryanpass', $user->getSalt());
14261375 $user->setPassword($password);
14271376
1377+ In order for this to work, just make sure that you have the encoder for your
1378+ user class (e.g. ``Acme\UserBundle\Entity\User ``) configured under the ``encoders ``
1379+ key in ``app/config/security.yml ``.
1380+
14281381..caution ::
14291382
14301383 When you allow a user to submit a plaintext password (e.g. registration
@@ -2077,5 +2030,4 @@ Learn more from the Cookbook
20772030.. _`JMSSecurityExtraBundle` :http://jmsyst.com/bundles/JMSSecurityExtraBundle/1.2
20782031.. _`FOSUserBundle` :https://github.com/FriendsOfSymfony/FOSUserBundle
20792032.. _`implement the\S erializable interface` :http://php.net/manual/en/class.serializable.php
2080- .. _`functions-online.com` :http://www.functions-online.com/sha1.html
20812033.. _`Timing attack` :http://en.wikipedia.org/wiki/Timing_attack