Расширение UserProvider для FOS UserBundle

Я создаю сайт с помощью Symfony2, и это будет сайт с белой меткой, где несколько доменов сопоставляются с одним и тем же сервером. Итак, coolsite.customer1.com и aservice.customer2.com сопоставляются с одним и тем же сайтом, но для конечного пользователя должны выглядеть по-разному. Я уже решил для доменов и загрузки уникальных конфигураций в качестве услуги.

С настройкой FOS UserBundle и запуском с пользовательским пользователем (в котором хранится domain_id) регистрация, вход в систему и т. д. работают нормально, за исключением того, что пользователи из домена1 также могут войти в домен2. Это ожидается в FOS UserBundle. Мне нужно внести изменения в пакет, чтобы он аутентифицировал пользователей только в том домене, которому они назначены.

Я создал userProvider, который расширяет исходный userProvider в FOS, и переопределил метод loadUserByUsername, чтобы также проверять домен. Смотри ниже:

use FOS\UserBundle\Security\UserProvider as FOSProvider;
use Symfony\Component\DependencyInjection\ContainerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Me\CoreBundle\Models\Core;

class UserProvider extends FOSProvider {

    /**
     *
     * @var ContainerInterface 
     */
    protected $container;


    public function __construct(UserManagerInterface $userManager, ContainerInterface $container) {
        parent::__construct($userManager);
        $this->container = $container;
    }

    /**
     * {@inheritDoc}
     */
    public function loadUserByUsername($username)
    {
        $core = $this->container->get('me_core');
        /* @var $core Core */

        $user = $this->findUserBy(array(
            'username'=>$username,
            'domain_id'=>$core->getDomainMap()->getId(),
        ));

        if (!$user) {
            throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
        }

        return $user;
    }

    public function findUserBy(array $criteria) {
        return $this->userManager->findUserBy($criteria);
    }

}

Я настроил службу следующим образом.

services:
  me.security.authentication.userprovider:
    class:  Me\UserBundle\Security\UserProvider
    arguments:
      - @fos_user.user_manager
      - @service_container

Мой security.yml выглядит так:

security:
    providers:
        me.security.authentication.userprovider:
            id: fos_user.user_provider.username

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/public, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/, role: ROLE_USER }

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

То, что происходит, когда я пытаюсь получить доступ к сайту, является исключением. "ServiceNotFoundException: служба "security.authentication.manager" зависит от несуществующей службы "security.user.provider.concrete.fos_userbundle"."

Я основывал свои изменения на этом рецепте кулинарной книги

Есть идеи? Я полностью озадачен этим.


person Wpigott    schedule 20.09.2012    source источник
comment
Что ж, мне удалось заставить работать измененное имя провайдера, потому что я забыл обновить провайдера в разделе firewalls/main/form_login. Теперь процесс входа в систему работает точно так же, как если бы я не вносил никаких изменений, и указанный мной провайдер не вызывается. Я смог убедиться, что он не вызывается, отбросив эхо и команду выхода в конструкторе.   -  person Wpigott    schedule 20.09.2012
comment
Ну, я смог решить это. Однако я не могу ответить на свой вопрос в течение 8 часов, поэтому я отмечу его решенным в этот момент и опубликую, как я его решил.   -  person Wpigott    schedule 20.09.2012


Ответы (1)


Я смог заставить его работать. Оказывается, мне нужно было сделать «id» таким же, как имя службы, которую я использовал. Закомментированные строки — это оригиналы, которые шли в комплекте.

security:
    providers:
        me.security.authentication.userprovider:
            id: me.security.authentication.userprovider
        #fos_userbundle:
            #id: fos_user.user_provider.username
person Wpigott    schedule 21.09.2012