我正在为User
实体创建自定义实体提供程序。但是当我在登录表单中输入用户名和密码时,我得到了这个例外:
There is no user provider for user "Ibw\UserBundle\Entity\User".
当我切换回默认的Doctrine实体提供程序时,一切顺利。
首先是我的security.yml
:
security:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: /login
check_path: /login_check
default_target_path: ibw_job_index
logout:
path: /logout
target: /
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
providers:
default_provider:
entity: { class: Ibw\UserBundle\Entity\User }
encoders:
Ibw\UserBundle\Entity\User: sha512
这是Ibw\UserBundle\Entity\User
类:
<?php
namespace Ibw\UserBundle\Entity;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Class User
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="Ibw\UserBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
protected $username;
/**
* @ORM\Column(type="string", length=40)
*/
protected $salt;
/**
* @ORM\Column(type="string", length=128)
*/
protected $password;
public function __construct(ContainerInterface $container)
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
$this->container = $container;
}
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function setPassword($password)
{
$encoder = $this->container->get('security.encoder_factory')->getEncoder($this);
$this->password = $encoder->encodePassword($password, $this->getSalt());
return $this;
}
/**
* @return Role[] The user roles
*/
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return $this->salt;
}
public function getUsername()
{
return $this->username;
}
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
public function serialize()
{
return serialize(array($this->id));
}
public function unserialize($serialized)
{
list($this->id) = unserialize($serialized);
}
public function getId()
{
return $this->id;
}
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
}
最后,这是我的Ibw\UserBundle\Repository\UserRepository
课程:
<?php
namespace Ibw\UserBundle\Repository;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$q = $this->createQueryBuilder('u')
->select('u')
->where('u.username = :username')
->setParameter('username', $username)
->getQuery();
try
{
$user = $q->getSingleResult();
}
catch (NoResultException $e)
{
$message = sprintf('Unable to find active admin identified by %s', $username);
throw new UsernameNotFoundException($message, 0, $e);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if(!$this->supportsClass($user))
{
$message = sprintf('Unsupported class type : %s', $class);
throw new UnsupportedUserException($message);
}
return $this->find($user->getId());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName());
}
}
修改:
我也尝试在JobeetBundle/Resources/config/services.yml
:
parameters:
ibw.user.provider.class: Ibw\UserBundle\Repository\UserRepository
ibw.user.provider.entity.class: Ibw\UserBundle\Entity\User
services:
ibw.user.provider:
class: %ibw.user.provider.class%
factory_service: doctrine
factory_method: getRepository
arguments:
- %ibw.user.provider.entity.class%
在jobeet/app/config/security.yml
:
providers:
default_provider:
id: ibw.user.provider
encoders:
Ibw\UserBundle\Entity\User: sha512
但不幸的是,在我发布登录表单后,它给了我完全相同的错误。
答案 0 :(得分:7)
我在ContextListener
课程中跟踪了这个问题,结果发现这是一个错字!
在这里:
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($user)) { //This should be $class not $user
$message = sprintf('Unsupported class type : %s', $class);
throw new UnsupportedUserException($message);
}
return $this->find($user->getId());
}
将if
更改为:
if (!$this->supportsClass($class)) {}
答案 1 :(得分:0)
您需要在用户提供商的定义中使用IbwUserBundle:User
表示法而不是entity: { class: Ibw\UserBundle\Entity\User }
,或者只需将用户提供商定义为服务并使用其名称。