Мультитенантное приложение Symfony 3.2 с несколькими точками входа Guard

Я реализую многопользовательское приложение, в котором клиент требует, чтобы я следовал определенной модели данных. Заказчику требовались две отдельные системы входа в систему, которые я внедряю с помощью системы защиты.

Первый используется для входа клиентов. Сложность здесь в том, что требуется хранить пароли пользователей в базе данных заказчика. Для этого у меня есть реализация системы защиты, которая сначала ищет имя пользователя в базе данных «логин». Из той же базы данных извлекаются (зашифрованные) параметры подключения к базе данных приложений пользователей. Используя эти параметры, соединение с базой данных приложения пользователя создается динамически («приложение»), и пользователь входит в систему, используя информацию в этой базе данных приложения. При последующих запросах страниц база данных приложений пользователей динамически подключается с помощью службы триггеров при каждой загрузке страницы. Все идет нормально.

Вторая система Guard используется для входа в серверную часть для выполнения задач управления. Эта система входа на самом деле намного проще и использует единую базу данных 'admin_login' для проверки учетных данных пользователей. (Таким образом, имя пользователя, пароль и все другие свойства пользователя находятся в одной базе данных). Проблема возникает после успешного входа в систему на реализации 2nd Guard. Переход на внутреннюю домашнюю страницу вызывает ошибку, и я не могу найти причину этого.

Сообщение об ошибке:

The class 'AppBundle\Entity\Login\Admin\AdminUser' was not found in the chain configured namespaces AppBundle\Entity\App

Ошибка возникает до выполнения любого кода из соответствующего контроллера. Когда я устанавливаю для элемента конфигурации «intercept_redirects» значение true, я вижу, что пользователь с правами администратора полностью авторизован до того, как произойдет перенаправление.

Моя конфигурация доктрины в config.yml

# Doctrine Configuration
doctrine:
    dbal:
        default_connection: app # specify the connexion used by default
        connections:
            login:
                driver:   pdo_mysql
                host:     '%database_login_host%'
                port:     '%database_login_port%'
                dbname:   '%database_login_name%'
                user:     '%database_login_user%'
                password: '%database_login_password%'
                charset:  utf8mb4
            admin_login:
                driver:   pdo_mysql
                host:     '%database_admin_host%'
                port:     '%database_admin_port%'
                dbname:   '%database_admin_name%'
                user:     '%database_admin_user%'
                password: '%database_admin_password%'
                charset:  utf8mb4
            app:
                driver:   pdo_mysql
                host:     '%database_app_host%'
                port:     '%database_app_port%'
                dbname:   '%database_app_name%'
                user:     '%database_app_user%'
                password: '%database_app_password%'
                charset:  utf8mb4

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"

        default_entity_manager: app # specify the EM used by default (when using console commands f.e)

        entity_managers:
            login:
                connection:       login
                naming_strategy:  doctrine.orm.naming_strategy.underscore
                auto_mapping:     false
                mappings:
                    AppBundle :
                        type:     annotation
                        dir:      Entity/Login/Customer
                        prefix:   AppBundle\Entity\Login\Customer
                        alias:    Login
            app:
                connection:       app
                naming_strategy:  doctrine.orm.naming_strategy.underscore
                auto_mapping:     false
                mappings:
                    AppBundle :
                        type:     annotation
                        dir:      Entity/App
                        prefix:   AppBundle\Entity\App
                        alias:    App
                filters:
                    customer_flt:
                        class:    AppBundle\Security\CustomerFilter
            admin:
                connection:       admin_login
                naming_strategy:  doctrine.orm.naming_strategy.underscore
                auto_mapping:     false
                mappings:
                    AppBundle :
                        type:     annotation
                        dir:      Entity/Login/Admin
                        prefix:   AppBundle\Entity\Login\Admin
                        alias:    Admin

Моя безопасность.yml

security:

    encoders:
        AppBundle\Entity\App\User:
          algorithm: bcrypt
          cost: 12
        AppBundle\Entity\Login\Admin\AdminUser:
          algorithm: bcrypt
          cost: 12

    role_hierarchy:
        ROLE_SUPER_ADMIN: ROLE_ADMIN
        ROLE_ADMIN:       ROLE_USER
    # http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        app:
            entity:
                class: AppBundle\Entity\App\User
                property: username

        admin:
            entity:
                class: AppBundle\Entity\Login\Admin\AdminUser
                property: login

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            pattern:  ^/app
            anonymous: ~
            guard:
                authenticators:
                    - app.security.login_form_authenticator
            logout:
               path:   /app/logout
               target: /
            provider: app

        admin:
            pattern:  ^/admin
            anonymous: ~
            guard:
                authenticators:
                    - backend.security.login_form_authenticator
            logout:
               path:   /admin/logout
               target: /
            provider: admin

    access_control:
            - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/admin, roles: ROLE_SUPER_ADMIN }
            - { path: ^/app/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/app, roles: ROLE_USER }

Что мне здесь не хватает?


person Daan    schedule 17.05.2017    source источник


Ответы (1)


Проблема решена! Просто обновление, чтобы каждый мог найти ответ, погуглив его.

Проблема была вызвана отсутствием свойства manager_name в разделе провайдеров файла security.yml. Это свойство обеспечивает сопоставление поставщика с конкретным entity_manager. Без них Symfony берет первый (или стандартный) менеджер сущностей, который (очевидно) терпит неудачу в моем сценарии.

providers:
    app:
        entity:
            class: AppBundle\Entity\App\User
            property: username
            manager_name: app

    admin:
        entity:
            class: AppBundle\Entity\Login\Admin\AdminUser
            property: login
            manager_name: admin

Немного документации по этому вопросу можно найти здесь: http://symfony.com/doc/current/security/entity_provider.html

person Daan    schedule 17.05.2017