Symfony2自定义密码编码器和密码哈希更新

问题描述:

我正在学习Symfony2通过移动一些wordpress博客到Symfony。我被登录程序卡住了。 Wordpress使用非标准密码散列,如$P$....,我想在用户登录时检查旧密码散列,并在密码正确时将其重新转换为bcrypt。到目前为止,我创建了custome编码器类来与symfony安全机制一起使用。Symfony2自定义密码编码器和密码哈希更新

<?php 
namespace Pkr\BlogUserBundle\Service\Encoder; 

use PHPassLib\Application\Context; 
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder; 
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; 
use Symfony\Component\Security\Core\Util\SecureRandom; 

class WpTransitionalEncoder implements PasswordEncoderInterface 
{ 

    public function __construct($cost = 13) 
    { 
     $secure = new SecureRandom(); 
     $this->_bcryptEncoder = new BCryptPasswordEncoder($secure, $cost); 
    } 

    public function isPasswordValid($encoded, $raw, $salt) 
    { 
     if (preg_match('^\$P\$', $encoded)) { 
      $context = new Context(); 
      $context->addConfig('portable'); 
      return $context->verify($raw, $encoded); 
     } 
     return $this->_bcryptEncoder->isPasswordValid($encoded, $raw, $salt); 
    } 

    public function encodePassword($raw, $salt) 
    { 
     return $this->_bcryptEncoder->encodePassword($raw, $salt); 
    } 
} 

我使用它作为一个服务:

#/src/Pkr/BlogUserBundle/Resources/config/services.yml 
services: 
    pkr_blog_user.wp_transitional_encoder: 
     class: Pkr\BlogUserBundle\Service\Encoder\WpTransitionalEncoder 

而且在security.yml:

#/app/config/security.yml 
security: 
encoders: 
    Pkr\BlogUserBoundle\Entity\User: 
     id: pkr_blog_user.wp_transitional_encoder 
     cost: 15 

我的问题是:

如何传递参数我的编码器服务形式在security.yml

我在问,因为cost: 15不起作用。

我应该在哪里放置密码哈希更新逻辑?我在想,莫比刚密码验证这样的事情后:

public function isPasswordValid($encoded, $raw, $salt) 
{ 
    if (preg_match('^\$P\$', $encoded)) { 
     $context = new Context(); 
     $context->addConfig('portable'); 
     $isValid = $context->verify($raw, $encoded); 
     if ($isValid) { 
      // put logic here... 
     } 
     return $isValid; 
    } 
    return $this->_bcryptEncoder->isPasswordValid($encoded, $raw, $salt); 
} 

,但它似乎在某种程度上就像错了地方吧。那么正确的方法是什么?

我会回答我自己的问题。

我把参数为我的编码器服务中config.yml

pkr_blog_user: 
    password_encoder: 
     cost: 17 

他们将被传递给我的包扩展类:

# /src/Pkr/BlogUserBundle/DependencyInjection/PkrBlogUserExtension.php 
namespace Pkr\BlogUserBundle\DependencyInjection; 

use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\Config\FileLocator; 
use Symfony\Component\HttpKernel\DependencyInjection\Extension; 
use Symfony\Component\DependencyInjection\Loader; 

/** 
* This is the class that loads and manages your bundle configuration 
* 
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} 
*/ 
class PkrBlogUserExtension extends Extension 
{ 
    /** 
    * {@inheritDoc} 
    */ 
    public function load(array $configs, ContainerBuilder $container) 
    { 
     $configuration = new Configuration(); 
     $config = $this->processConfiguration($configuration, $configs); 

     $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 
     $loader->load('services.yml'); 

     if ($config['password_encoder']['cost'] < 10) { 
      $config['password_encoder']['cost'] = sprintf('%02d', $config['password_encoder']['cost']); 
     } 
     $container->setParameter('pkr_blog_user.wp_transitional_encoder.cost', $config['password_encoder']['cost']); 

    } 
} 

我发现我可以用我自己的身份验证成功的处理程序,以便有一个好的地方可以放置密码rehash逻辑。不幸的是,在使用自定义处理程序时,symfony2不会将配置传递给类构造函数,但我找到了一种使其工作的方法。我在这里描述:

https://stackoverflow.com/a/15988399/1089412