2

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

我必须创建自己的 User 类(因为我的 salt 是用户名 =>,而默认类 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\Security\User”没有用户提供程序。

如何为我的 User 类设置我的 UserProvider?

谢谢

4

2 回答 2

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)));
}
于 2013-11-09T20:57:25.300 回答
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);
}
于 2013-11-09T07:58:38.437 回答