我真的可以使用第二双眼睛。我正在尝试使用Silex的SecurityServiceProvider和Doctrine MongoDB ODM创建自定义用户提供程序,并且在尝试登录时仍然收到以下错误:
RuntimeException in ContextListener.php line 177:
There is no user provider for user "FooBar\Document\User".
注意:如果我对用户进行硬编码,则效果很好
'users' => [
'admin' => [
'ROLE_ADMIN', '$2y$12$W6FYYG1YTdMUNSosk14jluYsCwTe5wL7qwi3bnRMsqQEShb.89OiG'
],
]
据我所知,我遵循了Silex文档,可以找到here。我验证它是从db中成功获取用户的,所以我知道这不是问题。以下是相关代码,包括来自app.php的片段,用户类和我的自定义用户提供程序类。
$app->register(new Neutron\Silex\Provider\MongoDBODMServiceProvider(), $dbConfig);
// Create document manager alias
$app['dm'] = $app['doctrine.odm.mongodb.dm'];
$app->register(new Silex\Provider\SecurityServiceProvider(), [
'security.firewalls' => [
'login' => [
'pattern' => '^/login$',
'anonymous' => true
],
'secured' => [
'pattern' => '^.*$',
'form' => [
'login_path' => '/login',
'check_path' => '/login/authenticate',
],
'logout' => [
'logout_path' => '/logout',
'target' => '/'
],
'users' => $app->share(function() use ($app) {
return new \FooBar\Repository\UserRepository($app['dm']);
})
],
'unsecured' => [
'anonymous' => true
]
],
'security.role_hierarchy' => [
'ROLE_ADMIN' => [
'ROLE_USER',
],
'ROLE_SUPER_ADMIN' => [
'ROLE_ADMIN',
'ROLE_ALLOWED_TO_SWITCH'
]
],
'security.access_rules' => [
['^/login', 'IS_AUTHENTICATED_ANONYMOUSLY'],
['^.*', 'ROLE_USER']
]
]);
$app['security.encoder.digest'] = $app->share(function() {
return new Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder(12);
});
namespace FooBar\Repository;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class UserRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
try {
$user = $this->dm->createQueryBuilder('\FooBar\Document\User')
->field('username')->equals($username)
->getQuery()
->getSingleResult();
} catch (NoResultException $e) {
throw new UsernameNotFoundException(sprintf(
'Unable to find an active User object identified by "%s".',
$username
), 0, $e);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === '\FooBar\Document\User' || is_subclass_of($class, '\FooBar\Document\User');
}
}
<?php
namespace FooBar\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* @ODM\Document(repositoryClass="FooBar\Repository\UserRepository")
*/
class User implements AdvancedUserInterface
{
/**
* Document Id
* @ODM\Id
*/
protected $id;
/**
* User first name
* @ODM\String
*/
protected $firstName;
/**
* User last name
* @ODM\String
*/
protected $lastName;
/**
* User email
* @ODM\String
* @ODM\UniqueIndex
*/
protected $email;
/**
* User username
* @ODM\String
* @ODM\UniqueIndex
*/
protected $username;
/**
* User password
* @ODM\String
*/
protected $password;
/**
* Whether or not user account is expired
* @ODM\Boolean
*/
protected $isAccountExpired;
/**
* Whether or not user account is locked
* @ODM\Boolean
*/
protected $isAccountLocked;
/**
* Whether or not user credentials are expired
* @ODM\Boolean
*/
protected $isCredentialsExpired;
/**
* Whether or not user is active
* @ODM\Boolean
*/
protected $isActive;
/**
* Whether or not user credentials are erased
* @ODM\Boolean
*/
protected $isCredentialsErased;
/**
* User roles
* @ODM\Collection
*/
protected $roles;
/
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->isAccountLocked = false;
$this->isAccountExpired = false;
$this->isCredentialsExpired = false;
$this->isCredentialsErased = false;
$this->roles = new ArrayCollection;
// Temporary
$this->roles = ['ROLE_USER'];
}
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
public function setEmail($email)
{
$this->email = ($email);
}
public function setUsername($username)
{
$this->username = $username;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getFirstName()
{
return $this->firstName;
}
public function getLastName()
{
return $this->lastName;
}
public function getEmail()
{
return $this->email;
}
public function getUsername()
{
return $this->username;
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return null;
}
public function getRoles()
{
return $this->roles;
}
public function isAccountNonExpired()
{
return !$this->isAccountExpired;
}
public function isAccountNonLocked()
{
return !$this->isAccountLocked;
}
public function isCredentialsNonExpired()
{
return !$this->isCredentialsExpired;
}
public function isCredentialsErased()
{
return $this->isCredentialsErased;
}
public function isEnabled()
{
return $this->isActive;
}
public function eraseCredentials()
{
$this->username = null;
$this->password = null;
$this->isActive = false;
$this->isAccountLocked = true;
$this->isAccountExpired = true;
$this->isCredentialsExpired = true;
$this->isCredentialsErased = true;
return $this;
}
public function serialize()
{
return serialize([
$this->id,
$this->firstName,
$this->lastName,
$this->email,
$this->username,
]);
}
public function unserialize($serialized)
{
list(
$this->id,
$this->firstName,
$this->lastName,
$this->email,
$this->username,
) = unserialize($serialized);
}
}
答案 0 :(得分:2)
get_class($user);
将返回
FooBar\Document\User
而不是
\FooBar\Document\User
所以,替换
$class === '\FooBar\Document\User'
通过
$class === 'FooBar\Document\User'