После обновления symfony сломалась авторизация

174
22 марта 2022, 19:50

Разрабатываю локально небольшой проект на symfony. Использую докер. Использовал symfony 4.3.8 Решил обновить symfony, после применения команды docker-compose run --rm manager-php-cli composer update симфони вместе со всеми пакетами обновилась до 4.3.11

После этого авторизация пользователя, которая до этого работала нормально, при попытке войти в систему выдаёт ошибку:

There is no user provider for user "App\Security\UserIdentity". Shouldn't the "supportsClass()" method of your user provider return true for this classname?

Кэш чистил и не раз. Пробовал и cache:clear, и вручную.

В чём может быть проблема? Неужели простым обновлением можно сломать проект? Вот мой security.yaml

security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
    fetcher:
        id: App\Security\UserProvider
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        anonymous: true
        user_checker: App\Security\UserChecker
        guard:
            authenticators:
                - App\Security\LoginFormAuthenticator
                - App\Security\OAuth\FacebookAuthenticator
            entry_point: App\Security\LoginFormAuthenticator
        remember_me:
            secret: '%kernel.secret%'
            lifetime: 604800
            path: /
        form_login: true
        logout:
            path: app_logout
            # where to redirect after logout
            # target: app_any_route
        # activate different ways to authenticate
        # https://symfony.com/doc/current/security.html#firewalls-authentication
        # https://symfony.com/doc/current/security/impersonating_user.html
        # switch_user: true
role_hierarchy:
    ROLE_ADMIN:
        - ROLE_USER
        - ROLE_MANAGE_USERS
        - ROLE_WORK_MANAGE_MEMBERS
        - ROLE_WORK_MANAGE_PROJECTS
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/signup, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/reset, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/oauth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: ROLE_USER }

Вот UserProvider.php

declare(strict_types=1);
namespace App\Security;
use App\ReadModel\User\AuthView;
use App\ReadModel\User\UserFetcher;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class UserProvider implements UserProviderInterface
{
    /**
     * @var UserFetcher
     */
    private $users;
    public function __construct(UserFetcher $users)
    {
        $this->users = $users;
    }
    public function loadUserByUsername($username): UserInterface
    {
        $user = $this->loadUser($username); // $username can be useremail@gmail.com or facebook:56474756967544769
        return self::identityByUser($user, $username);
    }
    public function refreshUser(UserInterface $identity): UserInterface
    {
        if(!$identity instanceof UserIdentity){
            throw new UnsupportedUserException('Invalid user class '.get_class($identity));
        }
        $user = $this->loadUser($identity->getUsername());
        return self::identityByUser($user, $identity->getUsername());
    }
    public function supportsClass($class): bool
    {
        return $class instanceof UserIdentity;
    }
    private function loadUser($username): AuthView
    {
        $chunks = explode(":", $username); // $username can be useremail@gmail.com or facebook:56474756967544769
        if(count($chunks) === 2 && $user = $this->users->findForAuthByNetwork($chunks[0], $chunks[1])){
            return $user;
        }
        if( ! $user = $this->users->findForAuthByEmail($username) ){
            throw new UsernameNotFoundException("");
        }
        return $user;
    }
    /**
     * $username must be:
     *              facebook:56474756967544769
     *     or       useremail@gmail.com
     *
     * @param AuthView $user
     * @param string   $username - т.к. при регистрации через соц. сеть email может быть пустым, пишем сюда $username, который может быть вида: useremail@gmail.com or facebook:56474756967544769
     * @return UserIdentity
     */
    private static function identityByUser(AuthView $user, string $username): UserIdentity
    {
        return new UserIdentity(
            $user->id,
            $user->email ?: $username,
            $user->password_hash ?: '',
            $user->name ?: $username,
            $user->role,
            $user->status
        );
    }
}

Вот UserIdentity.php

declare(strict_types=1);
namespace App\Security;
use App\Model\User\Entity\User\User;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class UserIdentity implements UserInterface, EquatableInterface
{
    /**
     * @var string
     */
    private $id;
    /**
     * @var string
     */
    private $username;
    /**
     * @var string
     */
    private $password;
    /**
     * @var string
     */
    private $display;
    /**
     * @var string
     */
    private $role;
    /**
     * @var string
     */
    private $status;
    public function __construct(string $id, string $username, string $password, string $display, string $role, string $status)
    {
        $this->id = $id;
        $this->username = $username;
        $this->password = $password;
        $this->display = $display;
        $this->role = $role;
        $this->status = $status;
    }
    public function getId(): string
    {
        return $this->id;
    }
    public function getUsername(): string
    {
        return $this->username;
    }
    public function getPassword(): string
    {
        return $this->password;
    }
    public function getDisplay(): string
    {
        return $this->display;
    }
    public function getRoles(): array
    {
        return [$this->role];
    }
    public function getStatus(): string
    {
        return $this->status;
    }
    public function isActive(): bool
    {
        return $this->status === User::STATUS_ACTIVE;
    }
    public function getSalt(): ?string
    {
        return null;
    }
    public function eraseCredentials(): void
    {
        return;
    }
    public function isEqualTo(UserInterface $user): bool 
    {
        if(!$user instanceof self){
            return false;
        }
        return
            $this->id === $user->id &&
            $this->password === $user->password &&
            $this->role === $user->role &&
            $this->status === $user->status;
    }
}
Answer 1

после обновления supportsClass в UserProvider возвращает false

поменял на

public function supportsClass($class): bool
{
    return $class === UserIdentity::class;
}
READ ALSO
PHP вывод массива

PHP вывод массива

Есть массив $data = array()В него записываются данные array_push($data, data)

204
Передача информации из component в app.vue

Передача информации из component в app.vue

Подскажите , при клике по кнопке которая находится в компоненте должен меняться state в appvue

133
Нужно заменить каждую букву слова, которое находится в массиве на * JS

Нужно заменить каждую букву слова, которое находится в массиве на * JS

При нажатии на кнопку cenzor нужно заменить каждую букву слова, которое находится в массиве на "*"Не понимаю как нужно поставить условие

90
Как встроить js код (javascript) в андроид

Как встроить js код (javascript) в андроид

Есть той сервис как Вебвизор у ЯндексМетрики, дан код как на картинке, и его нужно вставить в WebView в программеВидел однажды такую реализацию...

123