add option to define the access decision manager

This commit is contained in:
Christian Flothmann 2016-01-15 21:45:57 +01:00 committed by Christian Flothmann
parent ddc4b20934
commit e0913a2808
12 changed files with 196 additions and 7 deletions

View File

@ -59,6 +59,26 @@ class MainConfiguration implements ConfigurationInterface
$rootNode = $tb->root('security');
$rootNode
->beforeNormalization()
->ifTrue(function ($v) {
if (!isset($v['access_decision_manager'])) {
return true;
}
if (!isset($v['access_decision_manager']['strategy']) && !isset($v['access_decision_manager']['service'])) {
return true;
}
return false;
})
->then(function ($v) {
$v['access_decision_manager'] = array(
'strategy' => AccessDecisionManager::STRATEGY_AFFIRMATIVE,
);
return $v;
})
->end()
->children()
->scalarNode('access_denied_url')->defaultNull()->example('/foo/error403')->end()
->enumNode('session_fixation_strategy')
@ -73,11 +93,15 @@ class MainConfiguration implements ConfigurationInterface
->children()
->enumNode('strategy')
->values(array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, AccessDecisionManager::STRATEGY_CONSENSUS, AccessDecisionManager::STRATEGY_UNANIMOUS))
->defaultValue(AccessDecisionManager::STRATEGY_AFFIRMATIVE)
->end()
->scalarNode('service')->end()
->booleanNode('allow_if_all_abstain')->defaultFalse()->end()
->booleanNode('allow_if_equal_granted_denied')->defaultTrue()->end()
->end()
->validate()
->ifTrue(function ($v) { return isset($v['strategy']) && isset($v['service']); })
->thenInvalid('"strategy" and "service" cannot be used together.')
->end()
->end()
->end()
;

View File

@ -83,12 +83,17 @@ class SecurityExtension extends Extension
$container->setParameter('security.access.denied_url', $config['access_denied_url']);
$container->setParameter('security.authentication.manager.erase_credentials', $config['erase_credentials']);
$container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']);
$container
->getDefinition('security.access.decision_manager')
->addArgument($config['access_decision_manager']['strategy'])
->addArgument($config['access_decision_manager']['allow_if_all_abstain'])
->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied'])
;
if (isset($config['access_decision_manager']['service'])) {
$container->setAlias('security.access.decision_manager', $config['access_decision_manager']['service']);
} else {
$container
->getDefinition('security.access.decision_manager')
->addArgument($config['access_decision_manager']['strategy'])
->addArgument($config['access_decision_manager']['allow_if_all_abstain'])
->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']);
}
$container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']);
$container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']);

View File

@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Reference;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
abstract class CompleteConfigurationTest extends TestCase
{
@ -356,6 +357,29 @@ abstract class CompleteConfigurationTest extends TestCase
$this->assertTrue($this->getContainer('remember_me_options')->has('security.console.user_password_encoder_command'));
}
public function testDefaultAccessDecisionManagerStrategyIsAffirmative()
{
$container = $this->getContainer('access_decision_manager_default_strategy');
$this->assertSame(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $container->getDefinition('security.access.decision_manager')->getArgument(1), 'Default vote strategy is affirmative');
}
public function testCustomAccessDecisionManagerService()
{
$container = $this->getContainer('access_decision_manager_service');
$this->assertSame('app.access_decision_manager', (string) $container->getAlias('security.access.decision_manager'), 'The custom access decision manager service is aliased');
}
/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedExceptionMessage "strategy" and "service" cannot be used together.
*/
public function testAccessDecisionManagerServiceAndStrategyCannotBeUsedAtTheSameTime()
{
$container = $this->getContainer('access_decision_manager_service_and_strategy');
}
protected function getContainer($file)
{
$file = $file.'.'.$this->getFileExtension();

View File

@ -0,0 +1,16 @@
<?php
$container->loadFromExtension('security', array(
'providers' => array(
'default' => array(
'memory' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
),
));

View File

@ -0,0 +1,19 @@
<?php
$container->loadFromExtension('security', array(
'access_decision_manager' => array(
'service' => 'app.access_decision_manager',
),
'providers' => array(
'default' => array(
'memory' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
),
));

View File

@ -0,0 +1,20 @@
<?php
$container->loadFromExtension('security', array(
'access_decision_manager' => array(
'service' => 'app.access_decision_manager',
'strategy' => 'affirmative',
),
'providers' => array(
'default' => array(
'memory' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
),
));

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<provider name="default">
<memory>
<user name="foo" password="foo" roles="ROLE_USER" />
</memory>
</provider>
<firewall name="simple" pattern="/login" security="false" />
</config>
</srv:container>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<access-decision-manager service="app.access_decision_manager" />
<provider name="default">
<memory>
<user name="foo" password="foo" roles="ROLE_USER" />
</memory>
</provider>
<firewall name="simple" pattern="/login" security="false" />
</config>
</srv:container>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<access-decision-manager service="app.access_decision_manager" strategy="affirmative" />
<provider name="default">
<memory>
<user name="foo" password="foo" roles="ROLE_USER" />
</memory>
</provider>
<firewall name="simple" pattern="/login" security="false" />
</config>
</srv:container>

View File

@ -0,0 +1,8 @@
security:
providers:
default:
memory:
users:
foo: { password: foo, roles: ROLE_USER }
firewalls:
simple: { pattern: /login, security: false }

View File

@ -0,0 +1,10 @@
security:
access_decision_manager:
service: app.access_decision_manager
providers:
default:
memory:
users:
foo: { password: foo, roles: ROLE_USER }
firewalls:
simple: { pattern: /login, security: false }

View File

@ -0,0 +1,11 @@
security:
access_decision_manager:
service: app.access_decision_manager
strategy: affirmative
providers:
default:
memory:
users:
foo: { password: foo, roles: ROLE_USER }
firewalls:
simple: { pattern: /login, security: false }