Я использую guard в качестве уровня аутентификации для моего гибкого приложения Symfony 4.

Всякий раз, когда я ввожу свое имя пользователя и пароль, он автоматически перенаправляет меня на страницу входа, никакие ошибки не перенаправляют меня. В моих журналах указано, что я не могу войти в систему, но в форме ничего из этого не отображается.

Я новичок в symfony с точки зрения использования их полного стека, перешедшего с silx на symfony. Я просматривал документы по symfony и учебники, но ничего не работает.

Security.yml

security:
    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin, roles: ['ROLE_ADMIN', 'ROLE_SUPERUSER'] }
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    encoders:
        App\Entities\User:
            algorithm: bcrypt
            cost:      15
    providers:
        admin:
            id: App\Security\UserProviders\AdminUserServiceProvider
    firewalls:
        admin:
            anonymous: ~
            provider: admin
            pattern: ^/admin/
            logout:
                path: /admin/logout
                target: /admin/login
                invalidate_session: true
            guard:
                authenticators:
                    - App\Security\Authenticators\AdminAuthenticator
        main:
            anonymous: ~
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
            form_login: ~

SecurityController.php

class AuthController extends Controller
{
    /**
    * @Route("/admin/login", name="adm_login")
    * @param Request $request
    * @return Response
    */
    public function adminLoginAction(Request $request) : Response
    {
        $utils = $this->get('security.authentication_utils');


        return $this->render('Auth/adminLogin.twig', [
            'PageTitle' => 'Login',
            'error' => $utils->getLastAuthenticationError()
        ]);
    }

    /**
    * @Route("/admin/authenticate", name="security_login_check")
    */
    public function loginCheckAction()
    {

    }

    /**
    * @Route("/admin/logout", name="logout")
    */
    public function logoutAction()
    {

    }
}

AdminLogin.twig

{% extends 'Shared/admin-login.twig' %}

{% block headJavascript %}
    <script type="application/javascript" src="{{ absolute_url('/assets/dependencies/jquery-validation/js/jquery.validate.min.js') }}"></script>
{% endblock %}

{% block loginForm %}
    <div class="login-box">
        <div class="login-logo">
            Admin Login
        </div>

        <div class="login-box-body">
            {% if error %}
                <div class="alert alert-danger" role="alert">
                    <span class="fa fa-exclamation-circle"></span>&nbsp;{{ error.messageKey }}
                </div>
            {% endif %}

            <p class="login-box-msg">Sign in to start your session</p>

            <form role="form" id="frmLogin" action="{{ path('security_login_check') }}" method="post">
                <div class="form-group has-feedback">
                    <label for="eml" class="sr-only">Email Address</label>
                    <input type="email" id="eml" name="_username" class="form-control" placeholder="Email Address">
                    <span class="fa fa-envelope form-control-feedback"></span>
                </div>
                <div class="form-group has-feedback">
                    <label for="pwd" class="sr-only">Password</label>
                    <input type="password" id="pwd" name="_password" class="form-control" placeholder="Password">
                    <span class="fa fa-lock form-control-feedback"></span>
                </div>
                <div class="row">
                    <div class="col-xs-8">
                        &nbsp;
                    </div>
                    <div class="col-xs-4">
                        <input type="hidden" name="_csrf_token" value="{{ csrf_token('frmLogin') }}">
                        <button type="submit" class="btn btn-primary btn-block btn-flat">
                            <span class="fa fa-sign-in"></span> Sign In
                        </button>
                    </div>
                </div>
            </form>
            <a href="{{ path('AccountRecovery') }}">I forgot my password</a><br>
        </div>
    </div>
{% endblock %}

{% block bottomJavascript %}
    <script type="application/javascript" src="{{ absolute_url('/assets/dependencies/jquery-validation/js/jquery.validate.min.js') }}"></script>
    <script type="application/javascript" src="{{ absolute_url('/assets/js/lib/auth/admin-login.js') }}"></script>
{% endblock %}

AdminAuthenticator.php

class AdminAuthenticator extends AbstractFormLoginAuthenticator
{
    private $encoderFactory;
    private $csrfTokenManager;
    private $userService;
    private $failMessage = 'Invalid credentials';
    private $loginUrl = '/admin/login';
    private $successUrl = '/admin/';

    public function __construct(UserService $userService, EncoderFactoryInterface $encoderFactory, CsrfTokenManagerInterface $csrfTokenManager)
    {
        $this->userService = $userService;
        $this->encoderFactory = $encoderFactory;
        $this->csrfTokenManager = $csrfTokenManager;
    }

    public function getCredentials(Request $request)
    {
        if ($request->getPathInfo() !== '/admin/authenticate'|| !$request->isMethod('POST'))
        {
            return null;
        }

        $csrfToken = $request->request->filter('_csrf_token', null, FILTER_SANITIZE_STRING);

        if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken))) {
            throw new InvalidCsrfTokenException('Invalid session token.');
        }

        return [
            'username' => $request->request->filter('_username', null, FILTER_SANITIZE_STRING),
            'password' => $request->request->filter('_password', null, FILTER_SANITIZE_STRING),
        ];
    }
    public function getUser($credentials, UserProviderInterface $userProvider) : ?UserInterface
    {
        try
        {
            if (!$userProvider instanceof AdminUserServiceProvider)
            {
                throw new CustomUserMessageAuthenticationException('Invalid Provider');
            }

            return $userProvider->loadUserByUsername($credentials['username']);
        }
        catch (UsernameNotFoundException $e)
        {
            throw new CustomUserMessageAuthenticationException($e->getMessage());
        }
    }

    public function checkCredentials($credentials, UserInterface $user) : bool
    {
        $encoder = $this->encoderFactory->getEncoder($user);

        if ($encoder->isPasswordValid($user->getPassword(), $credentials['password'], $user->getSalt()))
        {
            return true;
        }

        throw new CustomUserMessageAuthenticationException($this->failMessage);
    }
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) : ?Response
    {
        return new RedirectResponse($this->successUrl);
    }

    public function supportsRememberMe() : bool
    {
        return false;
    }

    protected function getLoginUrl() : string
    {
        return $this->loginUrl;
    }

    public function supports(Request $request) : ?bool
    {
        return $request->headers->has('_username') && $request->headers->has('_password');
    }
}

Журнал ошибок:

[2018-05-15 23:04:38] request.INFO: Matched route "security_login_check". {"route":"security_login_check","route_parameters":{"_controller":"App\\Controller\\AuthController::loginCheckAction","_route":"security_login_check"},"request_uri":"http://dev.local.com/admin/authenticate","method":"POST"} []
[2018-05-15 23:04:38] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"admin","authenticators":1} []
[2018-05-15 23:04:38] security.DEBUG: Calling getCredentials() on guard configurator. {"firewall_key":"admin","authenticator":"App\\Security\\Authenticators\\AdminAuthenticator"} []
[2018-05-15 23:04:38] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2018-05-15 23:04:38] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /var/www/Websites/dev.local.com/vendor/symfony/security/Http/Firewall/AccessListener.php:68)"} []
[2018-05-15 23:04:38] security.DEBUG: Calling Authentication entry point. [] []
[2018-05-15 23:04:38] request.INFO: Matched route "adm_login". {"route":"adm_login","route_parameters":{"_controller":"App\\Controller\\AuthController::adminLoginAction","_route":"adm_login"},"request_uri":"http://dev.local.com/site-admin/login","method":"GET"} []
[2018-05-15 23:04:38] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"admin","authenticators":1} []
[2018-05-15 23:04:38] security.DEBUG: Calling getCredentials() on guard configurator. {"firewall_key":"admin","authenticator":"App\\Security\\Authenticators\\AdminAuthenticator"} []
[2018-05-15 23:04:38] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
1
Eman 16 Май 2018 в 06:22

1 ответ

Лучший ответ

Вы сделали здесь несколько ошибок

  • Проверка URL-адреса запроса и метода должна выполняться в методе supports.
  • Вы ищете заголовки вместо переменных запроса в вашем методе supports.

Замените его следующим.

public function supports(Request $request) : ?bool
{
    return $request->request->has('_username') && $request->request->has('_password');
}
2
Fabien Papet 18 Май 2018 в 08:36