doutan3040 2017-01-05 16:31
浏览 54

使用动态数据库连接进行身份验证 - 在链配置的命名空间中找不到类“用户”

I am working in a Symfony 2.8 project with dynamic database connection. As I am developing a SaaS (Software as a Service) application and have to handle with different subdomains, databases are set dynamically based on the subdomain registered. Then, as the user accesses the application for the first time, database is created and its schema updated.

My config file looks like:

doctrine:
dbal:
    default_connection: default
    connections:
        default:
            driver:   pdo_mysql
            host:     "%database_host%"
            port:     "%database_port%"
            dbname:   "%database_name%"
            user:     "%database_user%"
            password: "%database_password%"
            charset:  UTF8
        dynamic_conn:
            driver:   pdo_mysql
            host:     ~
            port:     ~
            dbname:   ~
            user:     ~
            password: ~
            charset:  UTF8

orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    default_entity_manager:   default
    entity_managers:
        default:
            connection:       default
            auto_mapping:     false
        dynamic_em:
            connection:       dynamic_conn
            auto_mapping:     true

There's a listener which is responsible to establish connection for this "new" database and the 'dynamic_conn' parameters are set dynamically. Something like this:

public function onKernelRequest(GetResponseEvent $event)
{
    $connection = $this->container->get(sprintf('doctrine.dbal.%s_connection', 'dynamic_conn'));
    $connection->close();

    // Get params defined in config.yml for dynamic connection, a.k.a 'dynamic_conn'
    $refConn = new \ReflectionObject($connection);
    $refParams = $refConn->getProperty('_params');
    $refParams->setAccessible('public'); //we have to change it for a moment

    $params = $refParams->getValue($connection);
    $params['dbname'] = $store['db_name'];
    $params['user'] = $store['db_user'];
    $params['password'] = $store['db_password'];

    $refParams->setAccessible('private');

    // Set params dynamically in 'config.yml' to access its entity manager
    $refParams->setValue($connection, $params);
    $this->container->get('doctrine')->resetManager('dynamic_em');

    // Grab right entity manager to setup schema
    $em = $this->container->get('doctrine')->getManager('dynamic_em');
    $metadatas = $em->getMetadataFactory()->getAllMetadata();

    $schemaTool = new SchemaTool($em);
    $schemaTool->dropDatabase($store['db_name']);

    if (!empty($metadatas)) {
        $schemaTool->createSchema($metadatas);
    }
}

Then, when I want to execute some query using dynamic connection with the entity manager I call the manager and execute it, like this:

    $em = $this->container->get('doctrine')->getManager('dynamic_em');

    $products = $em
        ->createQueryBuilder()
        ->select('partial p.{id}')
        ->from('AdminBundle\Entity\Product', 'p')
        ->getQuery()
        ->getResult()
    ;

All this works fine! My main problem is for authentication. I tried to use the FOSUserBundle (already used in other project) however I had some troubles and decided to use "Load Security Users from the Database". My entity "User" is created accordingly the documentation and my 'security.yml' looks like this:

providers:
    in_memory:
        memory: ~

    # Admin
    admin:
        entity:
            class: AdminBundle\Entity\User
            property: login
            manager_name: dynamic_em

   firewalls:
        ...

        admin_private:
            provider: admin
            pattern: ^/admin
            form_login:
                login_path: admin_login
                check_path: admin_login_check
                default_target_path: admin_home
                use_referer: true
            logout:
                path: admin_logout
                target: admin_login

As there's the 'admin' provider, authentication process has to check in entity 'User' located in class 'AdminBundle\Entity\User' to perform login. However, application can't find the entity User. It gives the following error:

The class 'AdminBundle\Entity\User' was not found in the chain configured namespaces

I guess the main problem is because the configuration for security issues is set before the dynamic connection is set. Which will lead to security context trying to find something that it doesn't exist yet - my entity mapped dynamically! I've found some tracks here but none of them could help me figure it out a solution. Anyone with the same issue and/or a related solution? Any help is appreciated.

Thanks in advance.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥20 怎么用dlib库的算法识别小麦病虫害
    • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
    • ¥15 java写代码遇到问题,求帮助
    • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
    • ¥15 有了解d3和topogram.js库的吗?有偿请教
    • ¥100 任意维数的K均值聚类
    • ¥15 stamps做sbas-insar,时序沉降图怎么画
    • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
    • ¥15 关于#Java#的问题,如何解决?
    • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算