Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated article for modern Symfony practices and the use of bcrypt #5890

Merged
merged 1 commit into from
Dec 18, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 38 additions & 43 deletions cookbook/security/custom_provider.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ method.

This is how your ``WebserviceUser`` class looks in action::

// src/Acme/WebserviceUserBundle/Security/User/WebserviceUser.php
namespace Acme\WebserviceUserBundle\Security\User;
// src/AppBundle/Security/User/WebserviceUser.php
namespace AppBundle\Security\User;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
Expand Down Expand Up @@ -120,8 +120,8 @@ more details, see :class:`Symfony\\Component\\Security\\Core\\User\\UserProvider

Here's an example of how this might look::

// src/Acme/WebserviceUserBundle/Security/User/WebserviceUserProvider.php
namespace Acme\WebserviceUserBundle\Security\User;
// src/AppBundle/Security/User/WebserviceUserProvider.php
namespace AppBundle\Security\User;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
Expand Down Expand Up @@ -162,7 +162,7 @@ Here's an example of how this might look::

public function supportsClass($class)
{
return $class === 'Acme\WebserviceUserBundle\Security\User\WebserviceUser';
return $class === 'AppBundle\Security\User\WebserviceUser';
}
}

Expand All @@ -177,8 +177,8 @@ Now you make the user provider available as a service:

# app/config/services.yml
services:
webservice_user_provider:
class: Acme\WebserviceUserBundle\Security\User\WebserviceUserProvider
app.webservice_user_provider:
class: AppBundle\Security\User\WebserviceUserProvider

.. code-block:: xml

Expand All @@ -190,8 +190,8 @@ Now you make the user provider available as a service:
http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="webservice_user_provider"
class="Acme\WebserviceUserBundle\Security\User\WebserviceUserProvider"
<service id="app.webservice_user_provider"
class="AppBundle\Security\User\WebserviceUserProvider"
/>
</services>
</container>
Expand All @@ -202,8 +202,8 @@ Now you make the user provider available as a service:
use Symfony\Component\DependencyInjection\Definition;

$container->setDefinition(
'webservice_user_provider',
new Definition('Acme\WebserviceUserBundle\Security\User\WebserviceUserProvider')
'app.webservice_user_provider',
new Definition('AppBundle\Security\User\WebserviceUserProvider')
);

.. tip::
Expand All @@ -222,7 +222,7 @@ Modify ``security.yml``

Everything comes together in your security configuration. Add the user provider
to the list of providers in the "security" section. Choose a name for the user provider
(e.g. "webservice") and mention the id of the service you just defined.
(e.g. "webservice") and mention the ``id`` of the service you just defined.

.. configuration-block::

Expand All @@ -234,7 +234,7 @@ to the list of providers in the "security" section. Choose a name for the user p

providers:
webservice:
id: webservice_user_provider
id: app.webservice_user_provider

.. code-block:: xml

Expand All @@ -249,7 +249,7 @@ to the list of providers in the "security" section. Choose a name for the user p
<config>
<!-- ... -->

<provider name="webservice" id="webservice_user_provider" />
<provider name="webservice" id="app.webservice_user_provider" />
</config>
</srv:container>

Expand All @@ -261,7 +261,7 @@ to the list of providers in the "security" section. Choose a name for the user p

'providers' => array(
'webservice' => array(
'id' => 'webservice_user_provider',
'id' => 'app.webservice_user_provider',
),
),
));
Expand All @@ -279,7 +279,7 @@ users, e.g. by filling in a login form. You can do this by adding a line to the
# ...

encoders:
Acme\WebserviceUserBundle\Security\User\WebserviceUser: sha512
AppBundle\Security\User\WebserviceUser: bcrypt

.. code-block:: xml

Expand All @@ -294,9 +294,8 @@ users, e.g. by filling in a login form. You can do this by adding a line to the
<config>
<!-- ... -->

<encoder class="Acme\WebserviceUserBundle\Security\User\WebserviceUser"
algorithm="sha512"
/>
<encoder class="AppBundle\Security\User\WebserviceUser"
algorithm="bcrypt" />
</config>
</srv:container>

Expand All @@ -307,16 +306,15 @@ users, e.g. by filling in a login form. You can do this by adding a line to the
// ...

'encoders' => array(
'Acme\WebserviceUserBundle\Security\User\WebserviceUser' => 'sha512',
'AppBundle\Security\User\WebserviceUser' => 'bcrypt',
),
// ...
));

The value here should correspond with however the passwords were originally
encoded when creating your users (however those users were created). When
a user submits their password, the salt value is appended to the password and
then encoded using this algorithm before being compared to the hashed password
returned by your ``getPassword()`` method. Additionally, depending on your
options, the password may be encoded multiple times and encoded to base64.
a user submits their password, it's encoded using this algorithm and the result
is compared to the hashed password returned by your ``getPassword()`` method.

.. sidebar:: Specifics on how Passwords are Encoded

Expand All @@ -331,12 +329,12 @@ options, the password may be encoded multiple times and encoded to base64.
If your external users have their passwords salted via a different method,
then you'll need to do a bit more work so that Symfony properly encodes
the password. That is beyond the scope of this entry, but would include
sub-classing ``MessageDigestPasswordEncoder`` and overriding the ``mergePasswordAndSalt``
method.
sub-classing ``MessageDigestPasswordEncoder`` and overriding the
``mergePasswordAndSalt`` method.

Additionally, the hash, by default, is encoded multiple times and encoded
to base64. For specific details, see `MessageDigestPasswordEncoder`_.
To prevent this, configure it in your configuration file:
Additionally, you can configure the details of the algorithm used to hash
passwords. In this example, the application sets explicitly the cost of
the bcrypt hashing:

.. configuration-block::

Expand All @@ -347,10 +345,9 @@ options, the password may be encoded multiple times and encoded to base64.
# ...

encoders:
Acme\WebserviceUserBundle\Security\User\WebserviceUser:
algorithm: sha512
encode_as_base64: false
iterations: 1
AppBundle\Security\User\WebserviceUser:
algorithm: bcrypt
cost: 12

.. code-block:: xml

Expand All @@ -365,11 +362,9 @@ options, the password may be encoded multiple times and encoded to base64.
<config>
<!-- ... -->

<encoder class="Acme\WebserviceUserBundle\Security\User\WebserviceUser"
algorithm="sha512"
encode-as-base64="false"
iterations="1"
/>
<encoder class="AppBundle\Security\User\WebserviceUser"
algorithm="bcrypt"
cost="12" />
</config>
</srv:container>

Expand All @@ -380,12 +375,12 @@ options, the password may be encoded multiple times and encoded to base64.
// ...

'encoders' => array(
'Acme\WebserviceUserBundle\Security\User\WebserviceUser' => array(
'algorithm' => 'sha512',
'encode_as_base64' => false,
'iterations' => 1,
),
'AppBundle\Security\User\WebserviceUser' => array(
'algorithm' => 'bcrypt',
'cost' => 12,
)
),
// ...
));

.. _MessageDigestPasswordEncoder: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php