1

我尝试使用警卫(symfony 3.2)进行表单登录身份验证,但它不起作用。身份验证正在工作,但是当我被重定向到主页(accueil)时,我被重定向到登录页面而没有进行身份验证。
如果我把我的主页的控制器

$user = $this->get('security.token_storage')->getToken();
dump($user); die;

我可以看到我的用户、角色,但他没有经过身份验证。

DashboardController.php on line 23:
PostAuthenticationGuardToken {#133 ▼
 -providerKey: "main"
 -user: User {#457 ▶}
 -roles: array:1 [▼
   0 => Role {#120 ▼
     -role: "ROLE_SUPERADMIN"
   }
  ]    
-authenticated: false
-attributes: []
}

我错过了什么?

安全.ym

security:
encoders:
  EntBundle\Entity\User\User:
    algorithm: bcrypt

providers:
    database:
        entity:
          class: EntBundle:User\User
          property: username

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

    main:
        pattern:    ^/
        anonymous: ~
        logout: ~
        guard:
          authenticators:
            - ent.login_authenticator

测试验证器.php

namespace EntBundle\Security;

use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;

class TestAuthenticator extends AbstractGuardAuthenticator
{
private $em;
private $router;

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

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

    return [
        'username' => $request->request->get('_username'),
        'password' => $request->request->get('_password'),
    ];
}

public function getUser($credentials, UserProviderInterface $userProvider)
{
    $username = $credentials['username'];
    return $this->em->getRepository('EntBundle:User\User')->findOneBy(['username' => $username]);
}

public function checkCredentials($credentials, UserInterface $user)
{
  // this is just for test  
  return true;
}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
    $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
    $url = $this->router->generate('login');
    return new RedirectResponse($url);
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
    $url = $this->router->generate('accueil');
    return new RedirectResponse($url);
}

public function start(Request $request, AuthenticationException $authException = null)
{
    $url = $this->router->generate('login');
    return new RedirectResponse($url);
}

public function supportsRememberMe()
{
    return false;
}
}

仪表板控制器.php

namespace EntBundle\Controller\Dashboard;

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


class DashboardController extends Controller
{
/**
 * @Route("/accueil", name="accueil")
 */
public function indexAction()
{
    $user = $this->get('security.token_storage')->getToken();
    dump($user); die;
    return   $this->render('EntBundle:dashboard:dashboard_structure.html.twig');
}


/**
 * @Route("/login", name="login")
 */
public function loginAction()
{
    $authenticationUtils = $this->get('security.authentication_utils');
    $error = $authenticationUtils->getLastAuthenticationError();
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render('EntBundle::login.html.twig', [
        'last_username' => $lastUsername,
        'error' => $error,
    ]);
}

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

编辑:
感谢 leo_ap 的帮助,但问题并非来自那里。
配置会话是这样的:

session:
     handler_id:  session.handler.native_file
     save_path:   "%kernel.root_dir%/../var/sessions/%kernel.environment%"

如果我签入保存路径文件夹,我创建了会话文件但未经过身份验证。

_sf2_attributes|a:1:{s:26:"_security.main.target_path";s:29:"http://localhost:8000/accueil";}_sf2_flashes|a:0:{}_sf2_meta|a:3:{s:1:"u";i:1488245179;s:1:"c";i:1488244922;s:1:"l";s:1:"0";}

如果我使用 security.yml 尝试正常的 login_form,它工作正常......
我尝试使用 handler_id 和 save_path 为 null,但没有成功。

EDIT2:
我找到了为什么我总是被重定向到登录页面,因为我已经注销了!

[2017-02-28 09:16:34] security.INFO: The security token was removed due to an AccountStatusException. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationExpiredException(code: 0):  at /home/philippe/Documents/symfony/vendor/symfony/symfony/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php:86)"}

并在 GuardAuthenticationProvider.php (86)

   The listener *only* passes PreAuthenticationGuardToken instances.
   This means that an authenticated token (e.g.PostAuthenticationGuardToken)
   is being passed here, which happens if that token becomes "not authenticated" (e.g. happens if the user changes between requests).  
  In this case, the user should be logged out, so we will return an AnonymousToken to accomplish that.

但为什么 ???

4

1 回答 1

0

可能是您的 Session 没有保留令牌。检查您的 Session 配置,在里面:config.yml. 在framework选项中,有session. 查看handler_idandsave_path是如何配置的。可能是您的 php 安装无法处理配置路径上的会话。尝试将 null 设置为handler_idsave_path强制 php 使用其自己的内置配置来处理会话。

config.yml 文件:

framework:

    { .. Other configurations ..}

    session:
        handler_id:  null
        save_path:   null

    { .. More configurations ..}
于 2017-02-27T17:33:08.010 回答