为了账号安全,请及时绑定邮箱和手机立即绑定

symfony 4:身份验证成功后,它会重定向到管理区域并使用匿名令牌填充 TokenStorage

symfony 4:身份验证成功后,它会重定向到管理区域并使用匿名令牌填充 TokenStorage

PHP
慕侠2389804 2023-10-15 16:24:48
我有一个旧的 Symfony 3.1 站点,我将其升级到 Symfony 3.4.x,然后升级到 Symfony 4.4.11,但我没有将其升级到 symfony flex。我修复了很多问题,公共网站似乎可以正常工作。我必须重建身份验证,因为旧的身份验证与 sf4 不兼容。我按照这个 https://symfony.com/doc/4.4/security/form_login_setup.html这是: https: //symfonycasts.com/screencast/symfony-security/make-user我最终遇到的情况是,在成功进行身份验证后,当它重定向到管理区域时,它总是再次检查 LoginFormAuthenticator,这显然不支持管理区域,并且它会重定向回匿名用户的登录页面。关于这个问题有很多讨论,并尝试了我发现的所有内容,但没有找到解决方案。即使调试它也不行。会话保存在定义的路径中。它的id与浏览器中的PHPSESSID相同。站点运行 HTTP 协议。安全.ymlsecurity:    encoders:        AppBundle\Entity\User:            algorithm: bcrypt            cost: 12    providers:        user_provider:            entity:                class: AppBundle:User                property: email    firewalls:        dev:            pattern: ^/(_(profiler|wdt|error)|css|images|js)/            security: false        main:            stateless: true            pattern: ^/            anonymous: true            logout_on_user_change: true            guard:                authenticators:                    - AppBundle\Security\LoginFormAuthenticator            form_login:                provider: user_provider                username_parameter: email                csrf_token_generator: security.csrf.token_manager                login_path: app_login            logout:                path: app_logout    access_control:        - { path: ^/admin, roles: ROLE_ADMIN }        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }路由:app_login:    path:     /login    defaults: { _controller: AppBundle\Controller\BackendController:loginAction }app_logout:    path:     /logout    defaults: { _controller: AppBundle\Controller\BackendController:logoutAction }app_admin:    path:         /admin/{page}/{entry}    defaults:     { _controller: AppBundle\Controller\BackendController:showAction, entry: null }
查看完整描述

2 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

您必须更改您的防护身份验证器 AppBundle\Security\LoginFormAuthenticator

这向警卫解释您只需要检查登录页面上的凭据

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

https://symfony.com/doc/4.4/security/guard_authentication.html#avoid-authenticating-the-browser-on-every-request


查看完整回答
反对 回复 2023-10-15
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

我的同事找出了问题所在。实际上上面的代码有很多问题。

  1. 使用 GuardAuthenticator 接口已从 sf4 中删除: https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.0.md#security

  2. logout_on_user_change 不是必需的

  3. 不需要 LoginFormAuthenticator。

  4. stateless: true 是防火墙中的错误设置,但当我删除它时,它会抛出先前的错误:“无法刷新令牌,因为用户已更改。尝试刷新令牌后,令牌已取消身份验证。” 这件事发生是因为

  5. 在 isEqualTo 中我检查了$this->salt !== $user->getSalt()但它没有序列化

所以工作解决方案看起来像这样

  • 路由是一样的

  • 后端控制器是相同的

  • LoginFormAuthentication.php 已删除

安全.yml

security:

    encoders:

        AppBundle\Entity\User:

            algorithm: bcrypt

            cost: 12


    providers:

        user_provider:

            entity:

                class: AppBundle:User

                property: email


    firewalls:

        dev:

            pattern: ^/(_(profiler|wdt|error)|css|images|js)/

            security: false


        main:

            anonymous: ~

            provider: user_provider


            form_login:

                login_path: app_login

                check_path: app_login

                default_target_path: app_admin


            logout:

                path: app_logout


    access_control:

        - { path: ^/admin, roles: ROLE_ADMIN }

        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

用户.php


class User implements UserInterface, \Serializable, EquatableInterface

{


    // ..


    public function serialize()

    {

        return serialize(array(

            $this->id,

            $this->email,

            $this->password,

            $this->salt,

        ));

    }


    public function unserialize($serialized)

    {

        list (

            $this->id,

            $this->email,

            $this->password,

            $this->salt

            ) = unserialize($serialized, array('allowed_classes' => false));

    }


    public function isEqualTo(UserInterface $user)

    {

        if (!$user instanceof User) {

            return false;

        }


        if ($user->getId() == $this->getId()) {

            return true;

        }


        if ($this->password !== $user->getPassword()) {

            return false;

        }


        if ($this->salt !== $user->getSalt()) {

            return false;

        }


        if ($this->email !== $user->getUsername()) {

            return false;

        }


        return true;

    }

}


查看完整回答
反对 回复 2023-10-15
  • 2 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信