Guard的AuthenticationToken丢失

时间:2019-05-07 14:55:35

标签: symfony symfony4

由于某些特殊需要,我想按照Symfony文档(https://symfony.com/doc/current/security/form_login_setup.html)中的说明在我的Symfony App中使用Guard Authenticator。从身份验证器中的各种变量转储中可以看到,身份验证器的工作原理。但是在重定向之后,身份验证令牌接缝将丢失,我将再次重定向到登录表单。

Authenticator(用于调试问题的简化版本):

<?php 

namespace App\Security;

// use statements omitted

class LoginFormAuthenticatorSimple extends AbstractFormLoginAuthenticator 
{
    use TargetPathTrait;

    private $router;
    private $csrfTokenManager;


    public function __construct(RouterInterface $router,
                                CsrfTokenManagerInterface $csrfTokenManager) 
    {
        $this->router = $router;
        $this->csrfTokenManager = $csrfTokenManager;

    }

    public function supports(Request $request)
    {
        return 'login' === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'username' => $request->request->get('username'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['username']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider) {

        $user = new User();
        $user->setUid("jensp");

        $roles = ['ROLE_USER'];
        $user->setRoles($roles);

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        $username = $credentials["username"];
        $password = $credentials["password"];

        if ('' === (string) $password) {
            throw new BadCredentialsException('The presented password must not be empty.');
        }

        return $username === "jensp"  && $password === "test123";
    }

    public function createAuthenticatedToken(UserInterface $user, $providerKey) 
    {
        // Added to check if the token is created...
        dump($user);
        dump($providerKey);
        $token = parent::createAuthenticatedToken($user, $providerKey);

        dump($token);

        return $token;
    }

    public function onAuthenticationSuccess(Request $request, 
                                            TokenInterface $token, 
                                            $providerKey)
    {

        dump($token);
        dump($request);

        if ($targetPath = $this->getTargetPath($request->getSession(), 
                                               $providerKey)) {
            dump($targetPath);                                                   
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->router->generate('show_users'));
    }

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

security.yaml:

firewalls:
    main:
        pattern: ^/(users|groups|selfservice|login_check|form_login_ldap|login)
            anonymous: ~
            logout: ~

            guard:
                authenticators: 
                    - App\Security\LoginFormAuthenticatorSimple    
    access_control:
        - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/users, roles: IS_AUTHENTICATED_FULLY }
        - { path: ^/groups, roles: IS_AUTHENTICATED_FULLY }
        - { path: ^/self-service, roles: IS_AUTHENTICATED_FULLY }    

有没有暗示用户不保持身份验证的方式?

1 个答案:

答案 0 :(得分:2)

问题是您的getUser方法。您在此处创建一个新的User对象,而不是返回数据库(或存储用户信息的位置)中已有的对象。

尝试以下方法:

public function getUser($credentials, UserProviderInterface $userProvider): UserInterface
{
    try {
        $userProvider->loadUserByUsername($credentials['username']);
    } catch (UsernameNotFoundException $e) {
        throw new AuthenticationException('Username or password is wrong.');
    }
}

通过这种方式,您将使用注入的$userProvider来获取您已通过身份验证的用户。

侧面说明:您无需在会话中存储任何用户数据。您可以在控制器和服务中使用TokenStorageInterface来获取当前经过身份验证的用户。