Я пытаюсь реализовать FOSUserBundle с охраной на Symfony 4.1. Это мой аутентификатор:
<?php
namespace App\Security;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $em;
private $router;
private $passwordEncoder;
private $csrfTokenManager;
public function __construct(EntityManagerInterface $em, RouterInterface $router, UserPasswordEncoderInterface $passwordEncoder, CsrfTokenManagerInterface $csrfTokenManager)
{
$this->em = $em;
$this->router = $router;
$this->passwordEncoder = $passwordEncoder;
$this->csrfTokenManager = $csrfTokenManager;
}
public function getCredentials(Request $request)
{
$username = $request->request->get('_username');
$password = $request->request->get('_password');
$csrfToken = $request->request->get('_csrf_token');
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
$request->getSession()->set(
Security::LAST_USERNAME,
$username
);
return [
'username' => $username,
'password' => $password,
];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$username = $credentials['username'];
return $this->em->getRepository('App:User')
->findOneBy(['email' => $username]);
}
public function checkCredentials($credentials, UserInterface $user)
{
$password = $credentials['password'];
if ($this->passwordEncoder->isPasswordValid($user, $password)) {
return true;
}
return false;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$targetPath = null;
// if the user hit a secure page and start() was called, this was
// the URL they were on, and probably where you want to redirect to
$targetPath = $this->getTargetPath($request->getSession(), $providerKey);
if (!$targetPath) {
$targetPath = $this->router->generate('homepage');
}
return new RedirectResponse($targetPath);
}
protected function getLoginUrl()
{
return $this->router->generate('fos_user_security_login');
}
/**
* Does the authenticator support the given Request?
*
* If this returns false, the authenticator will be skipped.
*
* @param Request $request
*
* @return bool
*/
public function supports(Request $request)
{
if ($request->attributes->get('_route') !== 'fos_user_security_login'){
return false;
}
}
}
это мой файл security.yaml:
security:
encoders:
App\Entity\User: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\LoginFormAuthenticator
# form_login:
# csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%env(APP_SECRET)%'
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
И файл fos_user.yaml:
fos_user:
db_driver: 'orm'
user_class: App\Entity\User
firewall_name: main
service:
mailer: fos_user.mailer.twig_swift
from_email:
address: "[email protected]"
sender_name: "test"
registration:
form:
type: App\Form\UserRegistrationFormType
Всякий раз, когда я захожу в систему, я получаю следующую ошибку:
You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.
У меня установлен пакет безопасности, и я попытался выполнить шаги, указанные в официальной документации: https://symfony.com/doc/current/security/guard_authentication.html
И я следил за учебником по KnpUniversity, но это было для Symfony 3, и, похоже, что-то больше не работает так же.
Должно быть что-то действительно очевидное, чего я не вижу.
Любой совет будет очень признателен.
Информация о версии : - Symfony ^ 4.1 - FOSUserBundle ^ 2.1 - охранник ^ 4.1
Спасибо за ответ, я проверю и дам вам знать
Вы когда-нибудь исправляли ошибку? Я имею ту же самую проблему. Что ты сделал?




Думаю, это поможет вам лучше понять, что такое пользовательский пакет symfony guard и fos. Symfony Guard - вам не нужен FOSUserBundle
В основном хорошо, но устарело и отстой (см. HashPasswordListener).
Не сказал, что лучше всего следовать или что-то еще, но большая часть вещей все еще нужна, только реализация немного отличается. :-) @emix есть ли у вас ресурсы получше? Мне всегда интересно узнать больше о Symfony. : D
Услуги не требуются благодаря автоподводке. Пользовательский Сторожить был бы лучше вместо аутентификатора. И посмотрите, насколько круты средства проверки пользователей.
Правильно с функцией autowire сервисы больше не требуются. проверка пользователей - это способ обрабатывать группы и все остальное: D, и я согласен, что настраиваемая защита намного лучше, поэтому я поделился этим слайдом :) в fos user вы просто переписываете все по своим потребностям :(
Ага, поэтому я его никогда не использую;)
вы также можете написать базовую реализацию защиты и расширить ее в соответствии с вашими потребностями в каждом проекте, но вы можете выбрать то, что вы хотите для начала, и откуда, по вашему мнению, вам нужно будет расширить, на основе более старых проектов.
ПОДСКАЗКА: У меня была аналогичная проблема. Если я правильно помню, вам нужно удалить маршрут для страницы входа, который определен в маршрутах пользовательского пакета fos. Я знаю, что говорю двусмысленно, но проверьте маршруты. Он ищет страницу входа в систему fosuser, пока вы аутентифицируетесь с помощью guard.
Думаю, уместнее было бы еще комментарий.
Просто удар в темноте, но я думаю, вам нужно указать
form_login- см. (symfony.com/doc/current/security/form_login_setup.html) в качестве примера