Форма входа Symfony 2.3 не аутентифицируется

0

Я пытаюсь реализовать довольно базовую форму входа с Symfony2.3, но у меня возникает ошибка, когда я иногда перенаправляюсь на ожидаемую страницу после предоставления правильных учетных данных, но иногда нет (вместо этого я просто перенаправлен обратно на страницу входа в систему). Вот мой файл security.yml:

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
        Acme\MyBundle\Entity\User: sha512
    providers:
        main:
            id: acme.user.provider
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login_firewall:
            pattern: ^/login$
            security: false
        secured_area:
            pattern: ^/
            form_login: ~
            logout:
                path:   /logout
                target: /
    access_control:
        - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/, roles: ROLE_USER, requires_channel: https }

Вот мой SecurityController:

<?php

namespace Acme\MyBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContextInterface;

/**
 * Class SecurityController
 * @package Acme\MyBundle\Controller
 *
 * @Route("/")
 */
class SecurityController extends Controller
{
    /**
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @Route("/login", requirements={"_scheme" = "https"}, path="login")
     */
    public function LoginAction(Request $request)
    {
        $session = $request->getSession();

        // get the login error if there is one
        if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(
                SecurityContextInterface::AUTHENTICATION_ERROR
            );
        } elseif (null !== $session && $session->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
            $error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
            $session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
        } else {
            $error = '';
        }

        // last username entered by the user
        $lastUsername = (null === $session) ? '' : $session->get(SecurityContextInterface::LAST_USERNAME);

        return $this->render(
            'AcmeMyBundle:Security:login.html.twig',
            array(
                // last username entered by the user
                'last_username' => $lastUsername,
                'error'         => $error,
            )
        );
    }

    /**
     * @Route("/login_check", requirements={"_scheme" = "https"}, path="login_check")
     */
    public function LoginCheckAction()
    {

    }

    /**
     * @Route("/logout", requirements={"_scheme" = "https"}, path="logout")
     */
    public function LogoutAction()
    {

    }
}

И вот мой файл routing.yml:

_security:
    resource: "@AcmeMyBundle/Controller/SecurityController.php"
    type: annotation

Когда я предоставляю правильные учетные данные, я правильно зарегистрирован/перенаправлен на указанный URL примерно в 20% случаев. Другие 80% времени я просто перенаправлен обратно на страницу входа в форму без сообщения об ошибке. Я также не вижу сообщения об ошибке при попытке входа в систему с неправильными учетными данными.

ОБНОВЛЕНИЕ. Похоже, проблема заключается в том, что Symfony создает несколько сеансов в моей базе данных по каждому запросу. Я использую обработчик pdo.

Теги:
login

2 ответа

0
Лучший ответ

Оказывается, проблема связана с сущностью/таблицей Session в которой я сохранял сеанс. Я использовал PDOSessionHandler для хранения сеансов в базе данных и имел следующий $id в моем объекте Session ORM:

<?php

namespace Acme\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Session
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Session
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

$id не должен был иметь тип integer, но (очевидно (-_-) строки типа. После изменения свойства:

/**
 * @var integer
 *
 * @ORM\Column(type="string", length=255)
 * @ORM\Id
 */
private $id;

и запуск php app/console doctrine:schema:update --force, все работает правильно.

1

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

Я подозреваю, что раз, когда вы не можете войти в систему, вы непосредственно посещаете страницу входа в систему (/login) и, следовательно, пытаетесь войти в систему под своим "login_firewall", что бесполезно, потому что это полезно только для страницы /login. После того, как вы входите под свой login_firewall, вы перенаправлены в /, но вы не авторизованы под своим защищенным брандмауэром secure_area (который защищает /), поэтому он просит вас снова войти в систему, но на этот раз под правильным брандмауэром. Я бы предположил, что на этот раз вы сможете войти.

Это может быть проблемой, но независимо от того, избавиться от вашего login_firewall

  • 0
    То, что вы сказали о двух межсетевых экранах, охватывающих разные домены, имеет смысл, но я получаю цикл перенаправления после удаления login_firewall. Кроме того, я не уверен, что вы здесь абсолютно правы, потому что я не хочу, чтобы в моей защищенной области были анонимные пользователи. См. Symfony.com/doc/2.3/book/… и прокрутите вниз, чтобы избежать распространенных ошибок № 2.
  • 0
    Поцарапайте это, я думаю, что анонимные пользователи могут посещать страницу входа, но не защищенную область, поэтому это не должно иметь значения из-за контроля доступа, как вы сказали. Добавление anonymous: ~ в secured_area исправила проблему перенаправления, но не проблему цикла входа в систему.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню