Silex框架:创建UserProvider / PasswordEncoder / User

时间:2013-11-08 20:24:47

标签: php security authentication silex

我使用框架Silex,尤其是SecurityServiceProvider。

我必须创建自己的User类(因为我的salt是username =>,默认类是salt为null):

<?php
namespace Adh\Security;

use Symfony\Component\Security\Core\User\AdvancedUserInterface;

class User implements AdvancedUserInterface {

  private $username;
  private $password;

  public function __construct($username, $password)
  {
    $this->username = $username;
    $this->password = $password;
  }

  public function getRoles()
  {
    return array();
  }

  public function getPassword()
  {
    return $this->password;
  }

  public function getSalt()
  {
    return $this->username;
  }
...
}
直到这个,没问题。现在,我必须创建一个自定义UserProvider来从MySQL检索我的用户:

<?php
namespace Adh\Security;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Doctrine\DBAL\Connection;

class UserProvider implements UserProviderInterface
{
  private $conn;

  public function __construct(Connection $conn)
  {
    $this->conn = $conn;
  }

  public function loadUserByUsername($username)
  {
    $stmt = $this->conn->executeQuery('SELECT * FROM account WHERE username like ?', array($username));

    if (!$user = $stmt->fetch()) {
      throw new UsernameNotFoundException(sprintf('Le nom d\'utilisateur "%s" n\'existe pas', $username));
    }

    return new \Adh\Security\User($user['username'], $user['sha_pass_hash']);
  }
  ...
}

注册安全提供者:

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
  'security.firewalls' => array(
    'user' => array(
      'pattern' => '^/user',
      'form' => array('login_path' => '/connexion', 'check_path' => '/user'),
      'users' => $app->share(function () use ($app) {
        return new Adh\Security\UserProvider($app['db']);
      })
    )
  )
));

$app['security.encoder_factory'] = $app->share(function ($app) {
  return new EncoderFactory(
    array('Adh\Security\User' => new Adh\Security\PasswordEncoder())
    );
});

它有效,除非认证是肯定的(用户名和密码匹配)我有这个例外:

  

RuntimeException:用户没有用户提供程序   “的Adh \安全\用户”。

如何为我的User类设置UserProvider?

感谢的

2 个答案:

答案 0 :(得分:3)

我找到了解决方案。为了创建我的提供者,我遵循了这个例子:http://silex.sensiolabs.org/doc/providers/security.html#defining-a-custom-user-provider

在refreshUser方法中:

if (!$user instanceof User) {
   throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}

这对于默认的User类是正确的:我有自己的User类,因此会引发异常。

条件变为:

if (!$user instanceof \Adh\Security\User) {
   throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}

答案 1 :(得分:1)

你的功能

loadUserByUsername()

不会返回任何角色。默认情况下,返回Symfony \ Component \ Security \ Core \ User \ User记录,并将用户角色作为第三个参数。至少任何用户都必须有一个角色。

样品:

use Symfony\Component\Security\Core\User\User;

public function loadUserByUsername($username)
{
    $frameworkUser = new FrameworkUser($this->app);
    if (false === ($user = $frameworkUser->selectUser($username))) {
      throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
    }
    return new User($user['username'], $user['password'], $user['roles'], true, true, true, true);
}