Symfony 4 - FOSUserBundle - аутентификаторы Guard

Я пытаюсь реализовать 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

Просто удар в темноте, но я думаю, вам нужно указать form_login - см. (symfony.com/doc/current/security/form_login_setup.html) в качестве примера

Alex.Barylski 01.08.2018 20:20

Спасибо за ответ, я проверю и дам вам знать

Dennis de Best 02.08.2018 08:42

Вы когда-нибудь исправляли ошибку? Я имею ту же самую проблему. Что ты сделал?

Chad 01.11.2018 21:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
3
1 210
2

Ответы 2

Думаю, это поможет вам лучше понять, что такое пользовательский пакет symfony guard и fos. Symfony Guard - вам не нужен FOSUserBundle

В основном хорошо, но устарело и отстой (см. HashPasswordListener).

emix 07.08.2018 10:11

Не сказал, что лучше всего следовать или что-то еще, но большая часть вещей все еще нужна, только реализация немного отличается. :-) @emix есть ли у вас ресурсы получше? Мне всегда интересно узнать больше о Symfony. : D

Bogdan 07.08.2018 10:21

Услуги не требуются благодаря автоподводке. Пользовательский Сторожить был бы лучше вместо аутентификатора. И посмотрите, насколько круты средства проверки пользователей.

emix 07.08.2018 10:29

Правильно с функцией autowire сервисы больше не требуются. проверка пользователей - это способ обрабатывать группы и все остальное: D, и я согласен, что настраиваемая защита намного лучше, поэтому я поделился этим слайдом :) в fos user вы просто переписываете все по своим потребностям :(

Bogdan 07.08.2018 10:33

Ага, поэтому я его никогда не использую;)

emix 07.08.2018 10:55

вы также можете написать базовую реализацию защиты и расширить ее в соответствии с вашими потребностями в каждом проекте, но вы можете выбрать то, что вы хотите для начала, и откуда, по вашему мнению, вам нужно будет расширить, на основе более старых проектов.

Bogdan 07.08.2018 11:53

ПОДСКАЗКА: У меня была аналогичная проблема. Если я правильно помню, вам нужно удалить маршрут для страницы входа, который определен в маршрутах пользовательского пакета fos. Я знаю, что говорю двусмысленно, но проверьте маршруты. Он ищет страницу входа в систему fosuser, пока вы аутентифицируетесь с помощью guard.

Думаю, уместнее было бы еще комментарий.

Word Rearranger 18.10.2019 22:36

Другие вопросы по теме