2016-05-05 23 views
1

我是Symfony的新手,我正在學習如何使用Guard來驗證用戶身份。目前使用Symfony 2.8.4。Symfony的Guard啓動()功能不起作用

你可以在下面查看我所有的代碼,它主要來自我在網上找到的各種教程。

FormLoginAuthenticator類似乎start()函數不正確地檢測是否發送憑證。如果我訪問任何網頁像/登錄,/主頁,/ login_check等。我得到的所有的人相同的回報:

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

這裏是我的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; 
    } 
} 

這裏是我的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 
    } 
} 

的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 } 

最後的services.yml文件:

parameters: 

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

回答

0

添加這getCredentials()解決這方面的問題,但還有更多的解決:

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