How to implement custom encoding with symfony2 security

327 views Asked by At

So the problem that I've run into is the following: Currently, the symfony2 project I have has a user entity with its own methods for encrypting its password in the database:

private function blowfishCrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2a$%02d$',$cost);
    //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
    mt_srand();
    for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
    return crypt($password,$salt);
}

public function encryptPassword($string)
{
    $this->setEncryptedPassword($this->blowfishCrypt($string, 10));
}

The login method basically just checks the entered password like so:

if (crypt($userPost['password'], $user->getEncryptedPassword()) != $user->getEncryptedPassword())

Then it sets session variables, authToken and userId.

But because of that throughout the application calls are having to be made to ensure that the userId and authToken are set in the session - so that any action we want authenticated users only to have access to we have to do a check like:

if (!authToken) { return 401 } //not exactly, but you get the idea.

My temporary solution to clean up all those checks was to create an interface that all my controllers can implement that will run some code before the controller action, and can return a redirect if the user is not logged in. What I would like to do is rewrite all of this so that I can utilize symfony2's security layer. How can I accomplish this?

EDIT: I have a separate portal running from the same code base that uses an entirely different table (like an administration portal) for users. Assuming the above is possible, is this possible with symfony2's security features?

EDIT 2: Trying to get this all integrated, so the first step I thought would be to implement UserInterface in my User entity. I've done that, and here's my security.yml:

security:
  firewalls:
    secured_area:
      pattern: ^/
      anonymous: ~
      form_login:
        login_path: login
        check_path: login_check
  access_control:
    - { path: ^/., roles: IS_AUTHENTICATED_FULLY }
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/login.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/login_check.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/signup.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }
  providers:
    main:
      entity:
        class: BundleNamespace\Entity\User
        property: email
  encoders:
    Symfony\Component\Security\Core\User\User: plaintext

I get an infinite loop. Basically I need users to be able to access /, /login, /signup, etc, without logging in. Almost every other page will require an authenticated user. I haven't gotten to the custom password encoder yet, I figure that will be my last step. I want to get past this redirect loop problem. Any ideas?

2

There are 2 answers

0
jonathonh On BEST ANSWER

Don't want to go into too much detail because this turned out to be a pretty grueling process of conversion. My only advice would be - do this sort of thing from scratch and save yourself a headache.

0
Thomas Leclercq On

You have to use a custom encoder, not a self-made thing put on top of the user entitie...

Give a look at : https://stackoverflow.com/a/8175657/2858398

Then you can use native symfony connection method with your custom password encoder.