我想创建一个Custom EntityRepository来从数据库加载用户,所以我跟着http://symfony.com/doc/current/cookbook/security/entity_provider.html本教程。
现在我得到一个例外,我不知道为什么:
{"error":{"code":500,"message":"Internal Server Error","exception":[{"message":"The user provider must be an instance of WebserviceUserRepository (Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider was given)."
如果我从我的WebserviceUser仓库中删除extends EntityRepository
,并且还更改了security.ml和services.yml
,而不是身份验证工作,并且该类是WebserviceUserRepository的实例。
我正在使用Symfony 2.7
我希望有人可以帮助我,我开始把头发拉出来了; - )
我的Api Key Authenticator看起来像这样:
class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface,
AuthenticationFailureHandlerInterface {
public function createToken(Request $request, $providerKey)
{
// look for an apikey query parameter
$apiKey = $request->query->get('apikey');
// or if you want to use an "apikey" header, then do something like this:
// $apiKey = $request->headers->get('apikey');
if (!$apiKey) {
throw new BadCredentialsException('No API key found');
// or to just skip api key authentication
//return null;
}
return new PreAuthenticatedToken(
'anon.',
$apiKey,
$providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
**if (!$userProvider instanceof WebserviceUserRepository) {**
throw new \InvalidArgumentException(
sprintf(
'The user provider must be an instance of WebserviceUserRepository (%s was given).',
get_class($userProvider)
)
);
}
$apiKey = $token->getCredentials();
$username = $userProvider->getUsernameForApiKey($apiKey);
if (!$username) {
throw new AuthenticationException(
sprintf('API Key "%s" does not exist.', $apiKey)
);
}
$user = $userProvider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$apiKey,
$providerKey,
$user->getRoles()
);
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new Response("Authentication Failed.".$exception->getMessage(), 403);
}
这是我的用户回购:
class WebserviceUserRepository extends EntityRepository implements UserProviderInterface {
public function getUsernameForApiKey($apiKey)
{
// Look up the username based on the token in the database, via
// an API call, or do something entirely different
$username = 'username';
return $username;
}
public function loadUserByUsername($username)
{
// make a call to your webservice here
$userData = "";
// pretend it returns an array on success, false if there is no user
if (false) {
$password = 'password';
$salt = '';
$roles = array('roles' => 'ROLE_ADMIN');
return new WebserviceUser($username, $password, $salt, $roles);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
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->find($user->getUsername());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
我还将存储库类添加到我的实体对象:
* @ORM\Table()
* @ORM\Entity(repositoryClass="Moera\RestBundle\Entity\WebserviceUserRepository")
*/
class WebserviceUser implements UserInterface, \Serializable, EquatableInterface
我还在security.yml和services.yml中注册了bot类:
services:
webservice_user_provider:
class: Moera\RestBundle\Entity\WebserviceUserRepository
apikey_authenticator:
class: Moera\RestBundle\Security\ApiKeyAuthenticator
public: false
security:
encoders:
Moera\RestBundle\Entity\WebserviceUser:
algorithm: bcrypt
providers:
webservice_user_provider:
entity:
class: MoeraRestBundle:WebserviceUser
firewalls:
secured_area:
pattern: ^/
stateless: true
simple_preauth:
authenticator: apikey_authenticator
provider: webservice_user_provider
非常感谢你!
亲切的问候, 约翰内斯