8000 Introduce a FirewallConfig class · symfony/symfony@4aa2242 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4aa2242

Browse files
committed
Introduce a FirewallConfig class
Add a FirewallConfig object, pass it to the FirewallContext Add FirewallContextTest & FirewallConfigTest Populate FirewallConfig definition from SecurityExtension Add missing anonymous listener in FirewallConfig::listenerConfigs Add a functional test Fabbot fixes Fix security option value Add ContextAwareFirewallMapInterface Remove bool casts from getters CS/Spelling Fixes Remove FirewallConfig::listenerConfigs in favor of FirewallConfig::listeners; Add FirewallConfig::allowAnonymous() Add allowAnonymous()/isSecurityEnabled, update comments Fabbot fixes Fix deprecation message
1 parent 695549f commit 4aa2242

File tree

9 files changed

+483
-10
lines changed

9 files changed

+483
-10
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public function load(array $configs, ContainerBuilder $container)
110110
'Symfony\Component\Security\Core\Authorization\AccessDecisionManager',
111111
'Symfony\Component\Security\Core\Authorization\AuthorizationChecker',
112112
'Symfony\Component\Security\Core\Authorization\Voter\VoterInterface',
113+
'Symfony\Bundle\SecurityBundle\Security\FirewallConfig',
113114
'Symfony\Bundle\SecurityBundle\Security\FirewallMap',
114115
'Symfony\Bundle\SecurityBundle\Security\FirewallContext',
115116
'Symfony\Component\HttpFoundation\RequestMatcher',
@@ -236,14 +237,18 @@ private function createFirewalls($config, ContainerBuilder $container)
236237
$mapDef = $container->getDefinition('security.firewall.map');
237238
$map = $authenticationProviders = array();
238239
foreach ($firewalls as $name => $firewall) {
239-
list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds);
240+
$configId = 'security.firewall.map.config.'.$name;
241+
242+
list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
240243

241244
$contextId = 'security.firewall.map.context.'.$name;
242245
$context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context'));
243246
$context
244247
->replaceArgument(0, $listeners)
245248
->replaceArgument(1, $exceptionListener)
249+
->replaceArgument(2, new Reference($configId))
246250
;
251+
247252
$map[$contextId] = $matcher;
248253
}
249254
$mapDef->replaceArgument(1, $map);
@@ -258,8 +263,13 @@ private function createFirewalls($config, ContainerBuilder $container)
258263
;
259264
}
260265

261-
private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds)
266+
private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds, $configId)
262267
{
268+
// FirewallConfig
269+
$config = $container->setDefinition($configId, new DefinitionDecorator('security.firewall.config'));
270+
271+
$config->replaceArgument(0, $id);
272+
263273
// Matcher
264274
$matcher = null;
265275
if (isset($firewall['request_matcher'])) {
@@ -271,20 +281,28 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
271281
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
272282
}
273283

284+
$config->replaceArgument(1, (string) $matcher);
285+
$config->replaceArgument(2, $firewall['security']);
286+
274287
// Security disabled?
275288
if (false === $firewall['security']) {
276289
return array($matcher, array(), null);
277290
}
278291

292+
$config->replaceArgument(3, $firewall['stateless']);
293+
279294
// Provider id (take the first registered provider if none defined)
280295
if (isset($firewall['provider'])) {
281296
$defaultProvider = $this->getUserProviderId($firewall['provider']);
282297
} else {
283298
$defaultProvider = reset($providerIds);
284299
}
285300

301+
$config->replaceArgument(4, $defaultProvider);
302+
286303
// Register listeners
287304
$listeners = array();
305+
$listenerKeys = array();
288306

289307
// Channel listener
290308
$listeners[] = new Reference('security.channel_listener');
@@ -296,11 +314,14 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
296314
$contextKey = $firewall['context'];
297315
}
298316

317+
$config->replaceArgument(5, $contextKey);
318+
299319
$listeners[] = new Reference($this->createContextListener($container, $contextKey));
300320
}
301321

302322
// Logout listener
303323
if (isset($firewall['logout'])) {
324+
$listenerKeys[] = 'logout';
304325
$listenerId = 'security.logout_listener.'.$id;
305326
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener'));
306327
$listener->replaceArgument(3, array(
@@ -363,10 +384,13 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
363384
// Authentication listeners
364385
list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $configuredEntryPoint);
365386

387+
$config->replaceArgument(6, $configuredEntryPoint ?: $defaultEntryPoint);
388+
366389
$listeners = array_merge($listeners, $authListeners);
367390

368391
// Switch user listener
369392
if (isset($firewall['switch_user'])) {
393+
$listenerKeys[] = 'switch_user';
370394
$listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider));
371395
}
372396

@@ -376,7 +400,30 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
376400
// Exception listener
377401
$exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $configuredEntryPoint ?: $defaultEntryPoint, $firewall['stateless']));
378402

403+
if (isset($firewall['access_denied_handler'])) {
404+
$config->replaceArgument(7, $firewall['access_denied_handler']);
405+
}
406+
if (isset($firewall['access_denied_url'])) {
407+
$config->replaceArgument(8, $firewall['access_denied_url']);
408+
}
409+
379410
$container->setAlias(new Alias('security.user_checker.'.$id, false), $firewall['user_checker']);
411+
$config->replaceArgument(9, $firewall['user_checker']);
412+
413+
foreach ($this->factories as $position) {
414+
foreach ($position as $factory) {
415+
$key = str_replace('-', '_', $factory->getKey());
416+
if (array_key_exists($key, $firewall)) {
417+
$listenerKeys[] = $key;
418+
}
419+
}
420+
}
421+
422+
if (isset($firewall['anonymous'])) {
423+
$listenerKeys[] = 'anonymous';
424+
}
425+
426+
$config->replaceArgument(10, $listenerKeys);
380427

381428
return array($matcher, $listeners, $exceptionListener);
382429
}

src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@
111111
<service id="security.firewall.context" class="Symfony\Bundle\SecurityBundle\Security\FirewallContext" abstract="true">
112112
<argument type="collection" />
113113
<argument type="service" id="security.exception_listener" />
114+
<argument /> <!-- FirewallConfig -->
115+
</service>
116+
117+
<service id="security.firewall.config" class="Symfony\Bundle\SecurityBundle\Security\FirewallConfig" abstract="true" public="false">
118+
<argument /> <!-- name -->
119+
<argument /> <!-- request_matcher -->
120+
<argument /> <!-- security enabled -->
121+
<argument /> <!-- stateless -->
122+
<argument /> <!-- provider -->
123+
<argument /> <!-- context -->
124+
<argument /> <!-- entry_point -->
125+
<argument /> <!-- user_checker -->
126+
<argument /> <!-- access_denied_handler -->
127+
<argument /> <!-- access_denied_url -->
128+
<argument type="collection" /> <!-- listeners -->
114129
</service>
115130

116131
<service id="security.logout_url_generator" class="Symfony\Component\Security\Http\Logout\LogoutUrlGenerator" public="false">
@@ -119,7 +134,6 @@
119134
<argument type="service" id="security.token_storage" on-invalid="null" />
120135
</service>
121136

122-
123137
<!-- Provisioning -->
124138
<service id="security.user.provider.in_memory" class="Symfony\Component\Security\Core\User\InMemoryUserProvider" abstract="true" public="false" />
125139
<service id="security.user.provider.in_memory.user" class="Symfony\Component\Security\Core\User\User" abstract="true" public="false" />
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Security;
13+
14+
use Symfony\Component\Security\Http\FirewallMapInterface;
15+
use Symfony\Component\HttpFoundation\Request;
16+
17+
/**
18+
* This interface must be implemented by firewall maps that are able to return a
19+
* context.
20+
*
21+
* @author Robin Chalas <robin.chalas@gmail.com>
22+
*/
23+
interface ContextAwareFirewallMapInterface extends FirewallMapInterface
24+
{
25+
/**
26+
* Returns the firewall context for a given request.
27+
*
28+
* @param Request $request
29+
*
30+
* @return FirewallContext
31+
*/
32+
public function getContext(Request $request);
33+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Security;
13+
14+
/**
15+
* Object representation of a firewall configuration.
16+
*
17+
* @author Robin Chalas <robin.chalas@gmail.com>
18+
*/
19+
class FirewallConfig
20+
{
21+
private $name;
22+
private $requestMatcher;
23+
private $securityEnabled;
24+
private $stateless;
25+
private $provider;
26+
private $context;
27+
private $entryPoint;
28+
private $accessDeniedHandler;
29+
private $accessDeniedUrl;
30+
private $userChecker;
31+
private $listeners;
32+
33+
/**
34+
* Constructor.
35+
*
36+
* @param string $name
37+
* @param string $requestMatcher
38+
* @param bool $securityEnabled
39+
* @param bool $stateless
40+
* @param string $provider
41+
* @param string $context
42+
* @param string $entryPoint
43+
* @param string $accessDeniedHandler
44+
* @param string $accessDeniedUrl
45+
* @param string $userChecker
46+
* @param array $listeners
47+
*/
48+
public function __construct($name, $requestMatcher, $securityEnabled = true, $stateless = false, $provider = null, $context = null, $entryPoint = null, $accessDeniedHandler = null, $accessDeniedUrl = null, $userChecker = null, $listeners = array())
49+
{
50+
$this->name = $name;
51+
$this->requestMatcher = $requestMatcher;
52+
$this->securityEnabled = $securityEnabled;
53+
$this->stateless = $stateless;
54+
$this->provider = $provider;
55+
$this->context = $context;
56+
$this->entryPoint = $entryPoint;
57+
$this->accessDeniedHandler = $accessDeniedHandler;
58+
$this->accessDeniedUrl = $accessDeniedUrl;
59+
$this->userChecker = $userChecker;
60+
$this->listeners = $listeners;
61+
}
62+
63+
public function getName()
64+
{
65+
return $this->name;
66+
}
67+
68+
/**
69+
* Returns the request matcher service id.
70+
*
71+
* @return string
72+
*/
73+
public function getRequestMatcher()
74+
{
75+
return $this->requestMatcher;
76+
}
77+
78+
/**
79+
* Returns whether the security is enabled or not.
80+
*
81+
* @return bool
82+
*/
83+
public function isSecurityEnabled()
84+
{
85+
return $this->securityEnabled;
86+
}
87+
88+
/**
89+
* Returns whether the firewall allows anonymous or not.
90+
*
91+
* @return bool
92+
*/
93+
public function allowsAnonymous()
94+
{
95+
return in_array('anonymous', $this->listeners, true);
96+
}
97+
98+
/**
99+
* Returns whether the firewall is stateless or not.
100+
*
101+
* @return bool
102+
*/
103+
public function isStateless()
104+
{
105+
return $this->stateless;
106+
}
107+
108+
/**
109+
* Returns the provider service id.
110+
*
111+
* @return string
112+
*/
113+
public function getProvider()
114+
{
115+
return $this->provider;
116+
}
117+
118+
/**
119+
* Returns the context key.
120+
*
121+
* @return string
122+
*/
123+
public function getContext()
124+
{
125+
return $this->context;
126+
}
127+
128+
/**
129+
* Returns the entry_point service id.
130+
*
131+
* @return string
132+
*/
133+
public function getEntryPoint()
134+
{
135+
return $this->entryPoint;
136+
}
137+
138+
/**
139+
* Returns the user_checker service id.
140+
*
141+
* @return string
142+
*/
143+
public function getUserChecker()
144+
{
145+
return $this->userChecker;
146+
}
147+
148+
/**
149+
* Returns the access_denied_handler service id.
150+
*
151+
* @return string
152+
*/
153+
public function getAccessDeniedHandler()
154+
{
155+
return $this->accessDeniedHandler;
156+
}
157+
158+
/**
159+
* Returns the access_denied_url.
160+
*
161+
* @return string
162+
*/
163+
public function getAccessDeniedUrl()
164+
{
165+
return $this->accessDeniedUrl;
166+
}
167+
168+
/**
169+
* Returns all registered listeners.
170+
*
171+
* @return array An array of listener keys
172+
*/
173+
public function getListeners()
174+
{
175+
return $this->listeners;
176+
}
177+
}

0 commit comments

Comments
 (0)
0