简体   繁体   English

Symfony的Guard start()函数不起作用

[英]Symfony's Guard start() function not working

I'm new to Symfony and I'm learning how to use Guard to authenticate users. 我是Symfony的新手,我正在学习如何使用Guard来验证用户身份。 Currently using Symfony 2.8.4. 目前使用Symfony 2.8.4。

You can check all my code below, it's mostly from various tutorials I found online. 您可以在下面查看我的所有代码,它主要来自我在网上找到的各种教程。

It seems the start() function from the FormLoginAuthenticator class isn't properly detecting if credentials were sent or not. 似乎FormLoginAuthenticator类的start()函数未正确检测是否已发送凭据。 If I visit any page like /login, /homepage, /login_check, etc.. I get the same return on all of them: 如果我访问任何页面,如/ login,/ homepage,/ login_check等。我得到所有这些页面的相同回报:

{"message":"Username could not be found."}

Here's my FormLoginAuthenticator.php: 这是我的FormLoginAuthenticator.php:

namespace AppBundle\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Doctrine\ORM\EntityManager;

class FormLoginAuthenticator extends AbstractGuardAuthenticator
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    /*
     * This method will get called on every request that requires an authentication.
     * Its job is to read the authentication information contained in the request, and return it.
     */
    public function getCredentials(Request $request)
    {
        return array(
            'username' => $request->request->get('_username'),
            'password' => $request->request->get('_password'),
        );
    }

    /*
     * After getting the credentials, try to get the User associated with those credentials.
     * The value of the credentials is passed to getUser() as the $credentials argument.
     * The job of this method is to return an object implementing UserInterface.
     * If it does, the next step of the authentication will be called: checkCredentials().
     * Else, the authentication will fail and the method onAuthenticationFailure() will get called.
     */
    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        return $userProvider->loadUserByUsername($credentials['username']);
    }

    /*
     * The job of this method is to check if the credentials of the previously returned User are correct.
     * If it returns true, the user will be authenticated, and the method onAuthenticationSuccess() will be called.
     * If does not, the authentication fails and the method onAuthenticationFailure() is called.
     */
    public function checkCredentials($credentials, UserInterface $user)
    {
        $plainPassword = $credentials['password'];
        $encoder = $this->container->get('security.password_encoder');
        if (!$encoder->isPasswordValid($user, $plainPassword)) {
            throw new BadCredentialsException();
        }
    }

    /*
     * This method is called when the user is successfully authenticated.
     * It can return null, in which case the request continues to process as expected,
     * or return a Response object, in which case this Response will be transferred to the user.
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        $url = $this->router->generate('homepage');

        return new RedirectResponse($url);
    }

    /*
     * This method is called when the authentication fails.
     * Its job is to return a Response object that will be sent to the client.
     */
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        $data = array(
            'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
        );

        return new JsonResponse($data, 403);
    }

    /*
     * This gets called when the user tries to access a resource that requires authentication,
     * but no authentication information was found in the request.
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $url = $this->router->generate('security_login');
        return new RedirectResponse($url);
    }

    protected function getLoginUrl()
    {
        return $this->container->get('router')
            ->generate('security_login');
    }

    protected function getDefaultSuccessRedirectUrl()
    {
        return $this->container->get('router')
            ->generate('homepage');
    }

    public function supportsRememberMe()
    {
        return false;
    }
}

Here's my SecurityController.php: 这是我的SecurityController.php:

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class SecurityController extends Controller
{
    /**
     * @Route("/login", name="security_login")
     */
    public function loginAction()
    {
        $helper = $this->get('security.authentication_utils');
        return $this->render('security/login.html.twig', array(
            'error' => $helper->getLastAuthenticationError(),
        ));
    }

    /**
     * @Route("/login_check", name="security_login_check")
     */
    public function loginCheckAction()
    {
        // will never be executed
    }
}

The security.yml file: security.yml文件:

security:
    providers:
        your_db_provider:
            entity:
                class: AppBundle:User

    encoders:
        AppBundle\Entity\User: bcrypt

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: ~
            logout: ~

            guard:
                authenticators:
                    - app.form_login_authenticator

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_ADMIN }

And finally the services.yml file: 最后是services.yml文件:

parameters:

services:
    app.form_login_authenticator:
        class: AppBundle\Security\FormLoginAuthenticator
        arguments: ['@doctrine.orm.entity_manager']

Adding this to getCredentials() solves this particular problem but there are many more to fix: 将此添加到getCredentials()可解决此特定问题,但还有许多问题需要解决:

if ($request->getPathInfo() != '/login_check') {
    return;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM