2013-12-11 14 views
7

Sto sviluppando un'applicazione in Symfony per gestire più scuole. L'applicazione ha più database, uno per ogni scuola e più server CAS.Firewall multipli dinamici e server CAS in Symfony2

Se riesco solo una scuola, la configurazione sarebbe come questo:

# config.yml 
be_simple_sso_auth: 
    admin_sso: 
     protocol: 
      id: cas 
      version: 2 
     server: 
      id: cas 
      login_url: https://cas01.example.com/SCHOOLID/login 
      logout_url: https://cas01.example.com/SCHOOL_ID/logout 
      validation_url: https://cas01.example.com/SCHOOL_ID/serviceValidate 

# security.yml 
firewalls: 
    school: 
     pattern: ^/school/.*$ 
     trusted_sso: 
      manager: admin_sso 
      login_action: false 
      logout_action: false 
      create_users: true 
      created_users_roles: [ROLE_USER, ROLE_ADMIN] 
      login_path: /school/login 
      check_path: /school/login_check 
     logout: 
      path: /school/logout 
      target: /school 

Con una scuola tutto funziona bene.

Ogni scuola accede all'applicazione attraverso il percorso app.com/school/ID, per esempio app.com/school/29, app.com/school/54 ...

mi chiedo se non v'è modo di avere più firewall dinamico a seconda dell'ID. E utilizzare questo ID per reindirizzare ogni URL CAS:

https://cas01.example.com/school_29/login, https://cas01.example.com/school_54/login ...

----------- AGGIORNAMENTO 13/12/12 ------ -----

ho creato un nuovo file: app/config/cas.php, e ho aggiunto alcune impostazioni server CAS

# CAS 14 
$container->loadFromExtension('be_simple_sso_auth', array(
    'cas_14' => array(
     'protocol' => array(
      'id' => 'cas', 
      'version' => '2' 
     ), 
     'server' => array(
      'id' => 'cas', 
      'login_url' => 'https://cas01.example.com/14/login', 
      'logout_url' => 'https://cas01.example.com/14/logout', 
      'validation_url' => 'https://cas01.example.com/14/serviceValidate', 
     ), 
    ), 

)); 

# CAS 15 
$container->loadFromExtension('be_simple_sso_auth', array(
    'cas_15' => array(
     'protocol' => array(
      'id' => 'cas', 
      'version' => '2' 
     ), 
     'server' => array(
      'id' => 'cas', 
      'login_url' => 'https://cas01.example.com/15/login', 
      'logout_url' => 'https://cas01.example.com/15/logout', 
      'validation_url' => 'https://cas01.example.com/15/serviceValidate', 
     ), 
    ), 

)); 

e ho importare il file in config.yml

imports: 
    - { resource: parameters.yml } 
    - { resource: cas.php } 
    - { resource: security.yml } 

E aggiungo un nuovo firewall per ogni scuola:

firewalls: 
    backend_14: 
     pattern: ^/backend/school/14/.*$ 
     trusted_sso: 
      manager: cas_14 
      login_action: false #BeSimpleSsoAuthBundle:TrustedSso:login 
      logout_action: false #BeSimpleSsoAuthBundle:TrustedSso:logout 
      create_users: true 
      created_users_roles: [ROLE_USER, ROLE_ADMIN] 
      login_path: /backend/school/14/login 
      check_path: /backend/school/14/login_check 
     logout: 
      path: /backend/school/logout 
      target: /backend 

    backend_15: 
     pattern: ^/backend/school/15/.*$ 
     trusted_sso: 
      manager: cas_15 
      login_action: false #BeSimpleSsoAuthBundle:TrustedSso:login 
      logout_action: false #BeSimpleSsoAuthBundle:TrustedSso:logout 
      create_users: true 
      created_users_roles: [ROLE_USER, ROLE_ADMIN] 
      login_path: /backend/school/15/login 
      check_path: /backend/school/15/login_check 
     logout: 
      path: /backend/school/logout 
      target: /backend 

E tutto va bene!

Ora sto provando a generare tutte le dinamiche di configurazione cas.php da Entity School. In primo luogo i Prova a creare un metodo in SchoolController

public function loadCasConfig() 
{ 
    $em = $this->getDoctrine()->getManager(); 

    $schools= $em->getRepository('SchoolBundle:School') 
        ->findBy(array(), array('name'=> 'ASC')); 


    foreach ($schools as $school) { 

     $cas_name = 'cas_'.$school->getId(); 

     $container->loadFromExtension('be_simple_sso_auth', array(
      "$cas_name" => array(
       'protocol' => array(
        'id' => 'cas', 
        'version' => '2' 
       ), 
       'server' => array(
        'id' => 'cas', 
        'login_url' => "https://cas01.example.com/$school->getId()/login", 
        'logout_url' => "https://cas01.example.com/$school->getId()/logout", 
        'validation_url' => "https://cas01.example.com/$school->getId()/serviceValidate", 
       ), 
      ), 

     )); 

    } 
} 

e chiamarlo in archivio cas.php

<?php 

use Comp\BackendBundle\Controller\SchoolController; 

SchoolController::loadCasConfig(); 

ma ho questa eccezione:.

FileLoaderLoadException: Cannot import resource  
"C:\wamp\www\comp\app/config\cas.php" from  
"C:\wamp\www\comp\app/config\config.yml". (Runtime Notice: Non-static method  
Comp\BackendBundle\Controller\SchoolController::loadCasConfig() should not be  
called statically, assuming $this from incompatible context in  C:\wamp\www\comp\app\config\cas.php line 5) 

:(Poi cerco di inserisci il codice del metodo nel file cas.php:

use Doctrine\ORM\EntityManager; 
use Comp\SchoolBundle\Entity\School; 

$em = $this->getDoctrine()->getManager(); 

$schools= $em->getRepository('SchoolBundle:School') 
       ->findBy(array(), array('name'=> 'ASC')); 


foreach ($schools as $school) { 

    $cas_name = 'cas_'.$school->getId(); 

    $container->loadFromExtension('be_simple_sso_auth', array(
     "$cas_name" => array(
      'protocol' => array(
       'id' => 'cas', 
       'version' => '2' 
      ), 
      'server' => array(
       'id' => 'cas', 
       'login_url' => "https://cas01.example.com/$school->getId()/login", 
       'logout_url' => "https://cas01.example.com/$school->getId()/logout", 
       'validation_url' => "https://cas01.example.com/$school->getId()/serviceValidate", 
      ), 
     ), 

    )); 

} 

e ora ho:

FatalErrorException: Error: Call to undefined method 
Symfony\Component\DependencyInjection\Loader\PhpFileLoader::getDoctrine() in 
C:\wamp\www\comp\app\config\cas.php line 11 

Mi piacerebbe sapere come posso generare dinamicamente il file cas.php, ottenere i dati dal database.

+1

Perché è che avete bisogno di più firewall? Non sarebbe possibile instradare ogni accesso attraverso le stesse pagine login/login_check e quindi indirizzare la risposta dalla pagina di ricezione? – qooplmao

+0

** public function loadCasConfig() ** non è un metodo statico. creare una chiamata statica ... Tipo: public static function callme() {$ my = new static; return $ my-> loadCasConfig(); } –

risposta

1

Avevamo problema simile, quando una piattaforma è utilizzata da più siti web, quindi dobbiamo soluzione per esso ed ora ogni sito ha il proprio security.yml che importa principale security.yml

+0

Sì, ma devi scrivere questo security.yml a mano quando aggiungi un nuovo sito web ?? Potresti incollare un codice di esempio? – JGrinon

+0

Sì, è necessario scriverlo a mano (ma probabilmente si può avere un file fittizio per la generazione automatica) –

2

Esempio di codice:

public function registerContainerConfiguration(LoaderInterface $loader) 
{ 
    $loader->load(__DIR__.'/config/sites/' . $this->_activeSite . '/config.yml'); 
    $configPath = __DIR__ . '/config/sites/' . $this->_activeSite . '/config_' . $this->getEnvironment() . '.yml'; 
    if (file_exists($configPath)) { 
     $loader->load($configPath); 
    } 

    $loader->load(__DIR__.'/config/servers/' . $this->getServer() . '.yml'); 
    $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 

    //per-site overrides 
    if (file_exists(__DIR__.'/config/sites/local_' . $this->_activeSite . '.yml')) { 
     $loader->load(__DIR__.'/config/sites/local_' . $this->_activeSite . '.yml'); 
    } 
} 
1

funzione pubblica loadCasConfig() non è un metodo statico. creare una chiamata statica ...

Ti piace questa:

public function loadCasConfig() 
{ 
    $em = $this->getDoctrine()->getManager(); 

    $schools= $em->getRepository('SchoolBundle:School') 
        ->findBy(array(), array('name'=> 'ASC')); 


    foreach ($schools as $school) { 

     $cas_name = 'cas_'.$school->getId(); 

     $container->loadFromExtension('be_simple_sso_auth', array(
      "$cas_name" => array(
       'protocol' => array(
        'id' => 'cas', 
        'version' => '2' 
       ), 
       'server' => array(
        'id' => 'cas', 
        'login_url' => "https://cas01.example.com/$school->getId()/login", 
        'logout_url' => "https://cas01.example.com/$school->getId()/logout", 
        'validation_url' => "https://cas01.example.com/$school->getId()/serviceValidate", 
       ), 
      ), 

     )); 

    } 
} 

public static function loadCasConfigStatic(){ 
    $my = new static; 
    return $my->loadCasConfig(); 
} 

Poi (il vostro cas.php):

<?php 

use Comp\BackendBundle\Controller\SchoolController; 

SchoolController::loadCasConfigStatic();