如何在UserProvider中获取子域

时间:2013-03-30 22:01:26

标签: security symfony dependency-injection fosuserbundle

我正在进行多租户服务,即我验证用户:

用户名,密码,子域名

我使用FOSUserBundle

我想使用UserProvider从其调用的wchich域中了解,然后让用户查找。

问题是我无法访问@request,无论我尝试使用容器还是设置注射

“ScopeWideningInjectionException:检测范围扩大注入”

有没有正确的方法可以在验证(make user login)用户名时将FOSUserBundle扩展为请求知晓?

3 个答案:

答案 0 :(得分:0)

您是否尝试过“更改UserProvider的范围?http://symfony.com/doc/current/cookbook/service_container/scopes.html

my_user_provider:
    class: Acme\HelloBundle\UserProvider
    scope: request
    arguments: [@request]

不确定它是否适用于这种情况。安全的东西很棘手。

另一种方法是创建一个REQUEST侦听器,让它拉出子域,然后将其注入用户提供程序。

答案 1 :(得分:0)

我遇到了同样的问题,使用Symfony 2.1我能够直接在我的提供商中提供@service_container参数,然后获取请求......

自从我更新到SF 2.2后,不再工作了!

即使您设置"范围:活动",或" public:true"在你的配置中。

如果你试图通过中间监听器来获取请求,它也不会起作用......从SF2.2开始,请求似乎没有及时注入或类似的事情。

所以我在这里如何获得提供商内部的请求,我不知道它是否干净但这是我找到的唯一解决方案,我粘贴了2个解决方案,适用于sf 2.2和sf 2.1 :

SF 2.2

提供者类:

use Symfony\Component\HttpFoundation\Request;

// ...

class WebsiteUserProvider implements UserProviderInterface
{
    private $websiteUrl;

    // ...

    public function __construct(UserManager $userManager)
    {
        $this->userManager = $userManager;

        // Works for sf2.2, init manually the request
        $request = Request::createFromGlobals();
        $this->websiteUrl = $request->getHost();
    }

    // ...
}

那就是它!


SF 2.1

提供者类:

// ...

class WebsiteUserProvider implements UserProviderInterface
{
    private $websiteUrl;

    // ...

    public function __construct($container, UserManager $userManager)
    {
        $this->userManager = $userManager;

        if ($container->isScopeActive('request')) {
            $this->websiteUrl = $container->get('request')->getHost();
        }
    }

    // ...
}

配置:

sybio_website.user_provider:
    class: Sybio\Bundle\WebsiteBundle\Security\Authentication\Provider\WebsiteUserProvider
    arguments: [@service_container, @sybio.user_manager]

答案 2 :(得分:0)

最后我这样做了:

使用SyndMultiTenantBundle多租户建议使用domainstrategy

并使其与FOSUserBundle一起使用:

  1. 创建新的UserManager& UserRepository类
  2. 覆盖您的UserManager:loadUserByUsername方法直接查询您的存储库
  3. 编译器传递使用您的自定义使用管理器(更改
    定义类)
  4. 在tenant.found上添加一个监听器以调用
    $ userManager-> setTenant($ event-> getTenant())将租户传递到
    存储库范围
  5. 感谢来自SyndicateTheory的Adrian

    它就像一个魅力 - 享受!