2012-09-20 12 views
7

Ich baue eine Website mit Symfony2 und es wird eine White-Label-Art von Website, wo mehrere Domänen auf dem gleichen Server zugeordnet werden. So würden coolsite.customer1.com und aservice.customer2.com auf die gleiche Site mappen, müssten aber für den Endbenutzer anders aussehen. Ich habe bereits die Domains gelöst und die einzigartigen Konfigurationen als Service geladen.BenutzerProvider für FOS erweitern UserBundle

Mit der FOS UserBundle Setup und läuft mit einem benutzerdefinierten Benutzer (mit der domain_id gespeichert ist), Registrierung, Anmeldung, usw. funktioniert gut, außer dass Benutzer von domain1 auch auf domain2 anmelden können. Dies wird im FOS UserBundle erwartet. Ich muss Änderungen an dem Paket vornehmen, damit nur Benutzer in der Domäne authentifiziert werden, der sie zugewiesen sind.

Ich habe einen userProvider erstellt, der den ursprünglichen userProvider in FOS erweitert und die Methode loadUserByUsername überschrieben hat, um auch die Domäne zu überprüfen. Siehe unten:

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); 
    } 

} 

Ich habe den Dienst mit den folgenden konfiguriert.

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

Mein security.yml sieht wie folgt aus:

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 

Was passiert, wenn ich versuche, die Site zuzugreifen eine Ausnahme. "ServiceNotFoundException: Der Dienst "security.authentication.manager" hat eine Abhängigkeit von einem nicht vorhandenen Service "security.user.provider.concrete.fos_userbundle

I basiert meine Änderungen auf This Cookbook Recipe

"." Irgendwelche Ideen? Ich bin darüber gründlich bestürzt.

+1

Nun, ich konnte den geänderten Namen des Providers zu funktionieren, weil ich vergessen habe, den Anbieter im Bereich Firewalls/main/form_login zu aktualisieren. Jetzt funktioniert der Anmeldevorgang genau so, als hätte ich keine Änderungen vorgenommen und der angegebene Provider wird nicht angerufen. Ich konnte bestätigen, dass es nicht aufgerufen wurde, indem ich im Konstruktor ein Echo und einen Exit-Befehl ablege. – Wpigott

+0

Nun, ich konnte es lösen. Ich bin jedoch nicht in der Lage, meine Frage für 8 Stunden zu beantworten, also werde ich es zu diesem Zeitpunkt als gelöst markieren und posten, wie ich es gelöst habe. – Wpigott

Antwort

6

Ich konnte es zur Arbeit bringen. Es stellte sich heraus, dass ich die "ID" mit dem Namen des Dienstes, den ich benutzte, identisch machen musste. Die kommentierten Zeilen sind die Originale, die mit dem Paket geliefert wurden.

Verwandte Themen