У меня возникли проблемы с тем, чтобы связка Neo4j OGM / Symfony работала с Symfony Guard. Я успешно добавил пользователей в базу данных. к сожалению, он не хочет входить в систему, и я получаю следующую ошибку:
Symfony\Component\Security\Core\Exception\AuthenticationServiceException: Class "App\Entity\Generic\User" is not a valid entity or mapped super class. in /home/vagrant/Code/support4neo/vendor/symfony/security/Core/Authentication/Provider/DaoAuthenticationProvider.php:85 Stack trace:
#0 /home/vagrant/Code/support4neo/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php(142): session_start()
#1 /home/vagrant/Code/support4neo/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php(299): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start()
#2 /home/vagrant/Code/support4neo/vendor/symfony/http-foundation/Session/Session.php(249): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->getBag('attributes')
#3 /home/vagrant/Code/support4neo/vendor/symfony/http-foundation/Session/Session.php(271): Symfony\Component\HttpFoundation\Session\Session->getBag('attributes')
#4 /home/vagrant/Code/support4neo/vendor/symfony/http-foundation/Session/Session.php(73): Symfony\Component\HttpFoundation\Session\Session->getAttributeBag()
#5 /home/vagrant/Code/support4neo/vendor/symfony/security/Http/Firewall/ContextListener.php(88): Symfony\Component\HttpFoundation\Session\Session->get('_security_main')
#6 /home/vagrant/Code/support4neo/vendor/symfony/security-bundle/Debug/WrappedListener.php(46): Symfony\Component\Security\Http\Firewall\ContextListener->handle(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#7 /home/vagrant/Code/support4neo/vendor/symfony/security-bundle/Debug/TraceableFirewallListener.php(35): Symfony\Bundle\SecurityBundle\Debug\WrappedListener->handle(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#8 /home/vagrant/Code/support4neo/vendor/symfony/security/Http/Firewall.php(56): Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener->handleRequest(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), Object(Symfony\Component\DependencyInjection\Argument\RewindableGenerator))
#9 /home/vagrant/Code/support4neo/vendor/symfony/security-bundle/EventListener/FirewallListener.php(48): Symfony\Component\Security\Http\Firewall->onKernelRequest(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#10 [internal function]: Symfony\Bundle\SecurityBundle\EventListener\FirewallListener->onKernelRequest(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher))
#11 /home/vagrant/Code/support4neo/vendor/symfony/event-dispatcher/Debug/WrappedListener.php(104): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher))
#12 /home/vagrant/Code/support4neo/vendor/symfony/event-dispatcher/EventDispatcher.php(212): Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\EventDispatcher\EventDispatcher))
#13 /home/vagrant/Code/support4neo/vendor/symfony/event-dispatcher/EventDispatcher.php(44): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#14 /home/vagrant/Code/support4neo/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php(139): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#15 /home/vagrant/Code/support4neo/vendor/symfony/http-kernel/HttpKernel.php(125): Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent))
#16 /home/vagrant/Code/support4neo/vendor/symfony/http-kernel/HttpKernel.php(66): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#17 /home/vagrant/Code/support4neo/vendor/symfony/http-kernel/Kernel.php(190): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /home/vagrant/Code/support4neo/public/index.php(37): Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#19 {main}
Что я мог делать не так?
Заранее спасибо!
Класс пользователя:
<?php
/**
* Created by PhpStorm.
* User: kevin.oosterhout
* Date: 24/04/2018
* Time: 20:58
*/
namespace App\Entity\Generic;
use GraphAware\Neo4j\Client\Client;
use GraphAware\Neo4j\OGM\Annotations as OGM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
*
* @OGM\Node(label = "User")
*/
class User implements UserInterface
{
/**
* @OGM\GraphId()
*/
protected $id;
/**
* @OGM\Property(type = "string")
*/
protected $firstname;
/**
* @OGM\Property(type = "string")
*/
protected $lastname;
/**
* @OGM\Property(type = "string")
*/
protected $email;
/**
* @OGM\Property(type = "string")
*/
protected $password;
/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @return mixed
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $firstname
*/
public function setFirstname($firstname): void
{
$this->firstname = $firstname;
}
/**
* @param mixed $lastname
*/
public function setLastname($lastname): void
{
$this->lastname = $lastname;
}
/**
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}
/**
* @param mixed $password
*/
public function setPassword($password): void
{
$this->password = $password;
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* @return (Role|string)[] The user roles
*/
public function getRoles()
{
return array('ROLE_USER');
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* @return string|null The salt
*/
public function getSalt()
{
return null;
}
/**
* Returns the username used to authenticate the user.
*
* @return string The username
*/
public function getUsername()
{
return $this->email;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
}
Класс аутентификатора:
<?php
/**
* Created by PhpStorm.
* User: kevin.oosterhout
* Date: 03/05/2018
* Time: 17:37
*/
namespace App\Security;
use App\Entity\Generic\User;
use App\Forms\LoginForm;
use GraphAware\Neo4j\OGM\EntityManager;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
public function getCredentials(Request $request)
{
return array(
'username' => $request->request->get('_username'),
'password' => $request->request->get('_password'),
);
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
if ($credentials['username'] === null){
return null;
}
$user = $userProvider->loadUserByUsername($credentials['username']);
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
return true;
}
protected function getLoginUrl()
{
// TODO: Implement getLoginUrl() method.
}
public function supports(Request $request)
{
return false;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// TODO: Implement onAuthenticationSuccess() method.
}
}
Безопасность.Ямл
security:
encoders:
App\Entity\Generic\User:
algorithm: bcrypt
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
UserProvider:
id: 'App\Security\UserProvider'
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
form_login:
login_path: login
check_path: login
guard:
authenticators:
- 'App\Security\LoginFormAuthenticator'
# activate different ways to authenticate
# http_basic: true
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: true
# https://symfony.com/doc/current/security/form_login_setup.html
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
Провайдер пользователя:
<?php
/**
* Created by PhpStorm.
* User: kevin.oosterhout
* Date: 04/05/2018
* Time: 07:38
*/
namespace App\Security;
use App\Entity\Generic\User;
use GraphAware\Neo4j\OGM\EntityManager;
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 UserProvider implements UserProviderInterface
{
protected $userRepository;
public function __construct(EntityManager $entityManager)
{
$this->userRepository = $entityManager->getRepository(User::class);
}
/**
* @param string $username
* @return null|User
*/
public function loadUserByUsername($username)
{
return $this->userRepository->findOneBy(['email' => $username]);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(
sprintf('Instance of %s is not support', get_class($user))
);
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return User::class === $class;
}
}
Редактировать: В настоящее время он не регистрирует меня и не выдает ошибок. Я выполнил шаги, описанные @dbrumann и @Christophe Willemsen
Я загрузил это: github.com/djkevino/Support4Neo




Думаю, проблема в вашем security.yaml:
providers:
UserProvider:
entity:
class: 'App\Entity\Generic\User'
property: email
Этот провайдер пытается использовать Doctrine ORM для загрузки пользователей из. Поскольку ваш пользовательский объект не является Doctrine-Entity, то есть в нем отсутствуют аннотации доктрины, он не работает. Несмотря на то, что пакет регистрирует менеджеров сущностей, кажется, что они не используются поставщиком пользователей.
Вы можете создать пользовательский провайдер, вдохновленный EntityUserProvider.
Я не уверен, придерживаются ли менеджеры сущностей ogm интерфейсов доктрины, но если они это сделают, вы можете настроить провайдера пользователя доктрины по умолчанию для использования диспетчера сущностей neo4j, настроив конфигурацию службы, но это настоящая боль, потому что у вас есть чтобы перезаписать службу UserProvider, а затем ввести новый ManagerRegistry с вашим менеджером сущностей в нем. Итак, создание собственного UserProvider действительно кажется предпочтительным способом.
Спасибо, это помогло мне продвинуться дальше, к сожалению, это все еще не входит в меня. Но я тоже не получаю сообщения об ошибке.
Посмотрите на веб-профилировщик на вкладке безопасности. Может быть, это даст вам некоторую информацию. Также мы надеемся, что dev.log даст вам ключ к разгадке. Например, я часто делаю ошибку, когда забываю назначить пользователю хотя бы одну группу, например ROLE_USER.
Ответ от @dbrumman правильный, вам понадобится собственный UserProvider.
У меня есть демонстрационный пример на Github, проверьте здесь: https://github.com/ikwattro/neo4j-ogm-symfony-security
Также существует PullRequest, который показывает, как добавлять роли на основе содержимого Neo4j:
https://github.com/ikwattro/neo4j-ogm-symfony-security/pull/1/files
Можете ли вы разместить репо на github со своим кодом для аутентификатора защиты, чтобы мы могли протестировать?