Symfony6: App.User 为 null(已验证用户未保存)原因是重定向后令牌丢失。

huangapple go评论63阅读模式
英文:

Symfony6 : App.User is null (Authenticated User is not saved) cause of token lost after redirection

问题

I am working in Symfony5.3 application (released in 2020 or 2021 I guess), and I have to take it over and upgrade its version to Symfony6.2.
Well, I am facing some problems during authentications, after calling app.user.username in my html.twig file I got: Impossible to access an attribute ("username") on a null variable.
Well, I see app.user is null even after a successful login, the User is not correctly set to app.

And I don't know what's missing, here is my code:

security.yaml

security:
    providers:
        database_users:
            id: App\Security\UsersProvider
    password_hashers:
        App\Entity\Users:
            algorithm: sha512
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: database_users
            logout:
                path: logout
                target: /login
                invalidate_session: true
            custom_authenticators:
                - App\Security\LoginFormAuthentificator

LoginForm

class LoginFormAuthentificator extends AbstractLoginFormAuthenticator
    use TargetPathTrait;
    public const LOGIN_ROUTE = 'login';
    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $userProvider;
    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager,
     UserProviderInterface $userProvider)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->userProvider = $userProvider;
    }
    ...
    ...
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('researchGeneral'));
    }

    public function authenticate(Request $request): \Symfony\Component\Security\Http\Authenticator\Passport\Passport {

        $encoder = new MessageDigestPasswordHasher('sha512', true, 5000);
        $user = $this->userProvider->loadUserByUsername($request->request->get("username"));
        if (!$user) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        $verif = $encoder->verify($user->getPassword(), $request->request->get("password"), 'sha512');
        if (!$verif) {
            throw a CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        return new SelfValidatingPassport(new UserBadge($request->request->get("username")));
    }

SecurityController

class SecurityController extends AbstractController
{
    /**
     * @Route("/login", name="login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        if ($this->getUser()) {
            return $this->redirectToRoute('researchGeneral');
        }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

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

It's not the full code of each file, but I presented the code snippet I believe are concerned by this.

[EDIT]
The exact problem is losing the access token after redirecting.

英文:

I am working in Symfony5.3 application (released in 2020 or 2021 I guess), and I have to take it over and upgrade its version to Symfony6.2.
Well, I am facing some problems during authentications, after calling app.user.username in my html.twig file I got : Impossible to access an attribute ("username") on a null variable.
Well, i see app.user is null even after successful login, the User is not correctly set to app.

And I don't know what's missing, here is my code:

security.yaml

security:
    providers:
        database_users:
            id: App\Security\UsersProvider
    password_hashers:
        App\Entity\Users:
            algorithm: sha512
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: database_users
            logout:
                path: logout
                target: /login
                invalidate_session: true
            custom_authenticators:
                - App\Security\LoginFormAuthentificator

LoginForm

class LoginFormAuthentificator extends AbstractLoginFormAuthenticator 
    use TargetPathTrait;
    public const LOGIN_ROUTE = 'login';
    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $userProvider;
    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager,
     UserProviderInterface $userProvider)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->userProvider = $userProvider;
    }
    ...
    ...
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('researchGeneral'));
    }

	public function authenticate(Request $request): \Symfony\Component\Security\Http\Authenticator\Passport\Passport {

        $encoder = new MessageDigestPasswordHasher('sha512', true, 5000);
        $user = $this->userProvider->loadUserByUsername($request->request->get("username"));
        if (!$user) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        $verif = $encoder->verify($user->getPassword(), $request->request->get("password"), 'sha512');
        if (!$verif) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        return new SelfValidatingPassport(new UserBadge($request->request->get("username")));
	}

SecurityController

class SecurityController extends AbstractController
{
    /**
     * @Route("/login", name="login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        if ($this->getUser()) {
                return $this->redirectToRoute('researchGeneral');
        }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

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

It's not the full code of each file, but I presented the code snippet I believe are concerned by this.

[EDIT]
The exact problem is losing the access token after redirecting.

答案1

得分: 0

在进行了大量研究后,我找到了问题所在。问题出现在Symfony\Component\Security\Http\Firewall\ContextListener中的hasUserChanged方法,它检测到了不希望的取消认证,因为我的userProvider中有一些错误。

无论如何,如果你遇到了这个问题,即app.user为null,或者在重定向后token发生变化,这绝对是由于你的组件(提供程序、实体、安全配置等)出现了故障,而很难有人能够为你进行调试。

英文:

Well, after a lot of research, i found the problem, it was the method hasUserChanged in Symfony\Component\Security\Http\Firewall\ContextListener it detected an undesirable de-authentication because i've some mistakes on my userProvider.

Anyway if you have encountered this problem, app.user null, or token changed after redirection is 100% due to malfunction of your components (provider or entity or security config or smth so) and it's really hard that someone can debug it for you.

huangapple
  • 本文由 发表于 2023年3月7日 21:52:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662863.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定