Symfony2 中的多个动态防火墙和 CAS 服务器
Posted
技术标签:
【中文标题】Symfony2 中的多个动态防火墙和 CAS 服务器【英文标题】:Multiple dynamic firewalls and CAS servers in Symfony2 【发布时间】:2013-12-29 12:02:25 【问题描述】:我正在 Symfony 中开发一个应用程序来管理多所学校。该应用程序有多个数据库,每个学校一个,以及多个 CAS 服务器。
如果我只管理一所学校,配置是这样的:
# 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
一所学校一切正常。
各学校通过路径app.com/school/ID访问应用,例如 app.com/school/29、app.com/school/54...
我想知道是否有办法根据 ID 设置多个动态防火墙。并使用此 ID 重定向每个 CAS URL:
https://cas01.example.com/school_29/login, https://cas01.example.com/school_54/login ...
------------ 2012 年 13 月 12 日更新 -----------
我创建了一个新文件:app/config/cas.php,并添加了一些 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',
),
),
));
我在 config.yml 中导入这个文件
imports:
- resource: parameters.yml
- resource: cas.php
- resource: security.yml
我为每所学校添加了一个新的防火墙:
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
一切顺利!
现在我正在尝试从 Entity School 生成所有 cas.php 配置动态。首先我尝试在 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",
),
),
));
并在 cas.php 文件中调用它
<?php
use Comp\BackendBundle\Controller\SchoolController;
SchoolController::loadCasConfig();
但我有这个例外:
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)
:(。然后我尝试在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",
),
),
));
现在我有了:
FatalErrorException: Error: Call to undefined method
Symfony\Component\DependencyInjection\Loader\PhpFileLoader::getDoctrine() in
C:\wamp\www\comp\app\config\cas.php line 11
我想知道如何动态生成文件 cas.php,从数据库中获取数据。
【问题讨论】:
为什么需要多个防火墙?难道不能通过相同的登录/登录检查页面路由每个登录,然后从接收页面路由回复吗? public function loadCasConfig() 不是静态方法。创建一个静态的..然后调用。喜欢: public static function callme() $my = new static;返回 $my->loadCasConfig(); 【参考方案1】:代码示例:
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');
【讨论】:
【参考方案2】:当一个平台被多个网站使用时,我们遇到了类似的问题,因此我们有解决方法,现在每个网站都有自己的 security.yml
导入主要的 security.yml
【讨论】:
是的,但是你添加新网站的时候必须手动写这个security.yml??你能粘贴示例代码吗? 是的,你需要手动编写(但可能你可以有一些虚拟文件用于自动生成)【参考方案3】:公共函数 loadCasConfig() 不是静态方法。创建一个静态的..然后调用。
像这样:
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();
然后(你的 cas.php):
<?php
use Comp\BackendBundle\Controller\SchoolController;
SchoolController::loadCasConfigStatic();
【讨论】:
以上是关于Symfony2 中的多个动态防火墙和 CAS 服务器的主要内容,如果未能解决你的问题,请参考以下文章